@prisma/orm-family-sql 8.0.0-rc.17-dev.23 → 8.0.0-rc.17-dev.24
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/orm-client.d.mts +32 -5
- package/dist/orm-client.d.mts.map +1 -1
- package/dist/orm-client.mjs +660 -623
- package/dist/orm-client.mjs.map +1 -1
- package/package.json +18 -18
package/dist/orm-client.mjs
CHANGED
|
@@ -377,7 +377,7 @@ function resolveIncludeRelation(contract, namespaceId, baseModelName, relationNa
|
|
|
377
377
|
const polymorphism = resolvePolymorphismInfo(contract, namespaceId, baseModelName);
|
|
378
378
|
const variant = variantName === void 0 ? void 0 : polymorphism?.variants.get(variantName);
|
|
379
379
|
let declaringModelName = baseModelName;
|
|
380
|
-
let
|
|
380
|
+
let localVariantName;
|
|
381
381
|
let relation;
|
|
382
382
|
if (variant !== void 0) {
|
|
383
383
|
const variantRelations = resolveModelRelations(contract, namespaceId, variant.modelName);
|
|
@@ -385,7 +385,7 @@ function resolveIncludeRelation(contract, namespaceId, baseModelName, relationNa
|
|
|
385
385
|
if (candidate !== void 0) {
|
|
386
386
|
relation = candidate;
|
|
387
387
|
declaringModelName = variant.modelName;
|
|
388
|
-
|
|
388
|
+
localVariantName = variant.strategy === "mti" ? variant.modelName : void 0;
|
|
389
389
|
}
|
|
390
390
|
}
|
|
391
391
|
const baseRelations = resolveModelRelations(contract, namespaceId, baseModelName);
|
|
@@ -412,7 +412,7 @@ function resolveIncludeRelation(contract, namespaceId, baseModelName, relationNa
|
|
|
412
412
|
relatedModelName: relation.to,
|
|
413
413
|
relatedNamespaceId: relation.toNamespace,
|
|
414
414
|
relatedTableName,
|
|
415
|
-
|
|
415
|
+
...ifDefined("localVariantName", localVariantName),
|
|
416
416
|
targetColumns,
|
|
417
417
|
localColumns,
|
|
418
418
|
cardinality: relation.cardinality,
|
|
@@ -677,6 +677,108 @@ function mapCursorValuesToColumns(contract, namespaceId, modelName, cursorValues
|
|
|
677
677
|
}
|
|
678
678
|
return mappedCursor;
|
|
679
679
|
}
|
|
680
|
+
const MAX_ALIAS_BYTES = 63;
|
|
681
|
+
const encoder = new TextEncoder();
|
|
682
|
+
function shortenToBytes(value, maxBytes) {
|
|
683
|
+
let shortened = "";
|
|
684
|
+
let bytes = 0;
|
|
685
|
+
for (const character of value) {
|
|
686
|
+
bytes += encoder.encode(character).length;
|
|
687
|
+
if (bytes > maxBytes) break;
|
|
688
|
+
shortened += character;
|
|
689
|
+
}
|
|
690
|
+
return shortened;
|
|
691
|
+
}
|
|
692
|
+
var TableScopeImpl = class TableScopeImpl {
|
|
693
|
+
#aliases;
|
|
694
|
+
constructor(aliases = []) {
|
|
695
|
+
this.#aliases = new Set(aliases);
|
|
696
|
+
}
|
|
697
|
+
alias(preferred) {
|
|
698
|
+
for (let n = 1;; n += 1) {
|
|
699
|
+
const suffix = n === 1 ? "" : `_${n}`;
|
|
700
|
+
const candidate = `${shortenToBytes(preferred, MAX_ALIAS_BYTES - suffix.length)}${suffix}`;
|
|
701
|
+
if (!this.#aliases.has(candidate)) {
|
|
702
|
+
this.#aliases.add(candidate);
|
|
703
|
+
return candidate;
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
}
|
|
707
|
+
aliasTable(storage) {
|
|
708
|
+
const alias = this.alias(storage.tableName);
|
|
709
|
+
const coordinate = Object.freeze({ ...storage });
|
|
710
|
+
return Object.freeze({
|
|
711
|
+
alias,
|
|
712
|
+
storage: coordinate,
|
|
713
|
+
column: (name) => ColumnRef.of(alias, name),
|
|
714
|
+
tableSource: (contract) => tableSourceForContract(contract, coordinate.namespaceId, coordinate.tableName, alias)
|
|
715
|
+
});
|
|
716
|
+
}
|
|
717
|
+
copy() {
|
|
718
|
+
return new TableScopeImpl(this.#aliases);
|
|
719
|
+
}
|
|
720
|
+
};
|
|
721
|
+
function createTableScope() {
|
|
722
|
+
return new TableScopeImpl();
|
|
723
|
+
}
|
|
724
|
+
function createModelTables(contract, scope, namespaceId, modelName, tableName) {
|
|
725
|
+
const root = scope.aliasTable({
|
|
726
|
+
namespaceId,
|
|
727
|
+
tableName
|
|
728
|
+
});
|
|
729
|
+
const variants = /* @__PURE__ */ new Map();
|
|
730
|
+
const mtiVariants = resolvePolymorphismInfo(contract, namespaceId, modelName)?.mtiVariants ?? [];
|
|
731
|
+
for (const variant of mtiVariants) variants.set(variant.modelName, scope.aliasTable({
|
|
732
|
+
namespaceId,
|
|
733
|
+
tableName: variant.table
|
|
734
|
+
}));
|
|
735
|
+
return {
|
|
736
|
+
scope,
|
|
737
|
+
root,
|
|
738
|
+
variants
|
|
739
|
+
};
|
|
740
|
+
}
|
|
741
|
+
function createCollectionTables(contract, namespaceId, modelName, tableName = resolveModelTableName(contract, namespaceId, modelName)) {
|
|
742
|
+
return createModelTables(contract, createTableScope(), namespaceId, modelName, tableName);
|
|
743
|
+
}
|
|
744
|
+
function createIncludeTables(contract, parent, relation) {
|
|
745
|
+
const scope = parent.scope.copy();
|
|
746
|
+
return {
|
|
747
|
+
tables: createModelTables(contract, scope, relation.relatedNamespaceId, relation.relatedModelName, relation.relatedTableName),
|
|
748
|
+
junction: relation.through === void 0 ? void 0 : scope.aliasTable({
|
|
749
|
+
namespaceId: relation.through.namespaceId,
|
|
750
|
+
tableName: relation.through.table
|
|
751
|
+
})
|
|
752
|
+
};
|
|
753
|
+
}
|
|
754
|
+
function createStatementTables(storage) {
|
|
755
|
+
const scope = createTableScope();
|
|
756
|
+
return {
|
|
757
|
+
scope,
|
|
758
|
+
root: scope.aliasTable(storage),
|
|
759
|
+
variants: /* @__PURE__ */ new Map()
|
|
760
|
+
};
|
|
761
|
+
}
|
|
762
|
+
function withScopeCopy(tables) {
|
|
763
|
+
return {
|
|
764
|
+
...tables,
|
|
765
|
+
scope: tables.scope.copy()
|
|
766
|
+
};
|
|
767
|
+
}
|
|
768
|
+
function requireVariantTable(tables, variantModelName) {
|
|
769
|
+
const variantTable = tables.variants.get(variantModelName);
|
|
770
|
+
if (variantTable === void 0) throw new InternalError(`Collection state has no aliased table for variant "${variantModelName}"`);
|
|
771
|
+
return variantTable;
|
|
772
|
+
}
|
|
773
|
+
function tableAliases(tables) {
|
|
774
|
+
return new Map([tables.root, ...tables.variants.values()].map((table) => [table.alias, table.storage]));
|
|
775
|
+
}
|
|
776
|
+
function variantColumnLabelPrefix(variantTable) {
|
|
777
|
+
return `${variantTable.alias}__`;
|
|
778
|
+
}
|
|
779
|
+
function variantColumnLabel(variantTable, column) {
|
|
780
|
+
return `${variantColumnLabelPrefix(variantTable)}${column}`;
|
|
781
|
+
}
|
|
680
782
|
function stripHiddenMappedFields(contract, namespaceId, modelName, mapped, hiddenColumns) {
|
|
681
783
|
if (hiddenColumns.length === 0) return;
|
|
682
784
|
const columnToField = getModelColumnFields(contract, namespaceId, modelName);
|
|
@@ -694,7 +796,7 @@ function createStorageRowMapper(contract, namespaceId, modelName) {
|
|
|
694
796
|
}
|
|
695
797
|
const mergedColumnToFieldCache = /* @__PURE__ */ new WeakMap();
|
|
696
798
|
function getMergedColumnToFieldMap(contract, namespaceId, baseModelName, variantModelName, variantTable) {
|
|
697
|
-
const cacheKey = `${namespaceId}:${baseModelName}:${variantModelName}:${variantTable ?? ""}`;
|
|
799
|
+
const cacheKey = `${namespaceId}:${baseModelName}:${variantModelName}:${variantTable?.alias ?? ""}`;
|
|
698
800
|
let perContract = mergedColumnToFieldCache.get(contract);
|
|
699
801
|
if (!perContract) {
|
|
700
802
|
perContract = /* @__PURE__ */ new Map();
|
|
@@ -705,25 +807,27 @@ function getMergedColumnToFieldMap(contract, namespaceId, baseModelName, variant
|
|
|
705
807
|
const baseMap = getModelColumnFields(contract, namespaceId, baseModelName);
|
|
706
808
|
const variantMap = getOwnColumnFields(contract, namespaceId, variantModelName);
|
|
707
809
|
const merged = { ...baseMap };
|
|
708
|
-
for (const [col, field] of Object.entries(variantMap)) if (variantTable) merged[
|
|
810
|
+
for (const [col, field] of Object.entries(variantMap)) if (variantTable) merged[variantColumnLabel(variantTable, col)] = field;
|
|
709
811
|
else merged[col] = field;
|
|
710
812
|
perContract.set(cacheKey, merged);
|
|
711
813
|
return merged;
|
|
712
814
|
}
|
|
713
|
-
function
|
|
815
|
+
function variantTableOf(tables, variant) {
|
|
816
|
+
return variant.strategy === "mti" ? requireVariantTable(tables, variant.modelName) : void 0;
|
|
817
|
+
}
|
|
818
|
+
function mapPolymorphicRow(contract, namespaceId, baseModelName, polyInfo, tables, row, variantName) {
|
|
714
819
|
const discriminatorValue = row[polyInfo.discriminatorColumn] ?? row["__prisma_polymorphic_discriminator"];
|
|
715
820
|
const variant = variantName ? polyInfo.variants.get(variantName) : typeof discriminatorValue === "string" ? polyInfo.variantsByValue.get(discriminatorValue) : void 0;
|
|
716
821
|
if (!variant) return mapKnownColumnNames(row, getModelColumnFields(contract, namespaceId, baseModelName));
|
|
717
|
-
|
|
718
|
-
return mapKnownColumnNames(row, getMergedColumnToFieldMap(contract, namespaceId, baseModelName, variant.modelName, mtiTable));
|
|
822
|
+
return mapKnownColumnNames(row, getMergedColumnToFieldMap(contract, namespaceId, baseModelName, variant.modelName, variantTableOf(tables, variant)));
|
|
719
823
|
}
|
|
720
|
-
function createPolymorphicRowMapper(contract, namespaceId, baseModelName, polyInfo, variantName) {
|
|
824
|
+
function createPolymorphicRowMapper(contract, namespaceId, baseModelName, polyInfo, tables, variantName) {
|
|
721
825
|
const baseMapper = captureColumnMapper(() => getModelColumnFields(contract, namespaceId, baseModelName));
|
|
722
826
|
const mappersByValue = /* @__PURE__ */ new Map();
|
|
723
827
|
let pinnedMapper = baseMapper;
|
|
724
828
|
for (const [name, variant] of polyInfo.variants) {
|
|
725
829
|
if (variantName && name !== variantName) continue;
|
|
726
|
-
const mapper = captureColumnMapper(() => getMergedColumnToFieldMap(contract, namespaceId, baseModelName, variant.modelName,
|
|
830
|
+
const mapper = captureColumnMapper(() => getMergedColumnToFieldMap(contract, namespaceId, baseModelName, variant.modelName, variantTableOf(tables, variant)));
|
|
727
831
|
if (variantName) pinnedMapper = mapper;
|
|
728
832
|
for (const [value, candidate] of polyInfo.variantsByValue) if (candidate === variant) mappersByValue.set(value, mapper);
|
|
729
833
|
}
|
|
@@ -872,43 +976,43 @@ function mergeAnnotations(plan, annotations) {
|
|
|
872
976
|
})
|
|
873
977
|
});
|
|
874
978
|
}
|
|
875
|
-
function
|
|
876
|
-
return
|
|
979
|
+
function bindWhereExpr(contract, expr, aliases) {
|
|
980
|
+
return bindWhereExprInScope(contract, expr, aliases);
|
|
877
981
|
}
|
|
878
|
-
function
|
|
982
|
+
function bindWhereExprInScope(contract, expr, aliases) {
|
|
879
983
|
return expr.accept({
|
|
880
984
|
columnRef(expr) {
|
|
881
|
-
return bindExpression(contract, expr);
|
|
985
|
+
return bindExpression(contract, expr, aliases);
|
|
882
986
|
},
|
|
883
987
|
identifierRef(expr) {
|
|
884
988
|
return expr;
|
|
885
989
|
},
|
|
886
990
|
subquery(expr) {
|
|
887
|
-
return bindExpression(contract, expr);
|
|
991
|
+
return bindExpression(contract, expr, aliases);
|
|
888
992
|
},
|
|
889
993
|
operation(expr) {
|
|
890
|
-
return bindExpression(contract, expr);
|
|
994
|
+
return bindExpression(contract, expr, aliases);
|
|
891
995
|
},
|
|
892
996
|
aggregate(expr) {
|
|
893
|
-
return bindExpression(contract, expr);
|
|
997
|
+
return bindExpression(contract, expr, aliases);
|
|
894
998
|
},
|
|
895
999
|
windowFunc(expr) {
|
|
896
|
-
return bindExpression(contract, expr);
|
|
1000
|
+
return bindExpression(contract, expr, aliases);
|
|
897
1001
|
},
|
|
898
1002
|
functionCall(expr) {
|
|
899
|
-
return bindExpression(contract, expr);
|
|
1003
|
+
return bindExpression(contract, expr, aliases);
|
|
900
1004
|
},
|
|
901
1005
|
cast(expr) {
|
|
902
|
-
return bindExpression(contract, expr);
|
|
1006
|
+
return bindExpression(contract, expr, aliases);
|
|
903
1007
|
},
|
|
904
1008
|
case(expr) {
|
|
905
|
-
return bindExpression(contract, expr);
|
|
1009
|
+
return bindExpression(contract, expr, aliases);
|
|
906
1010
|
},
|
|
907
1011
|
jsonObject(expr) {
|
|
908
|
-
return bindExpression(contract, expr);
|
|
1012
|
+
return bindExpression(contract, expr, aliases);
|
|
909
1013
|
},
|
|
910
1014
|
jsonArrayAgg(expr) {
|
|
911
|
-
return bindExpression(contract, expr);
|
|
1015
|
+
return bindExpression(contract, expr, aliases);
|
|
912
1016
|
},
|
|
913
1017
|
literal(expr) {
|
|
914
1018
|
return expr;
|
|
@@ -920,81 +1024,92 @@ function bindWhereExpr(contract, expr, namespaceId) {
|
|
|
920
1024
|
return expr;
|
|
921
1025
|
},
|
|
922
1026
|
list(expr) {
|
|
923
|
-
return bindExpression(contract, expr);
|
|
1027
|
+
return bindExpression(contract, expr, aliases);
|
|
924
1028
|
},
|
|
925
1029
|
binary(expr) {
|
|
926
|
-
const left = bindExpression(contract, expr.left);
|
|
1030
|
+
const left = bindExpression(contract, expr.left, aliases);
|
|
927
1031
|
const bindingColumn = left.kind === "column-ref" ? left : void 0;
|
|
928
|
-
return new BinaryExpr(expr.op, left, bindComparable(contract, expr.right, bindingColumn,
|
|
1032
|
+
return new BinaryExpr(expr.op, left, bindComparable(contract, expr.right, bindingColumn, aliases));
|
|
929
1033
|
},
|
|
930
1034
|
and(expr) {
|
|
931
|
-
return AndExpr.of(expr.exprs.map((part) =>
|
|
1035
|
+
return AndExpr.of(expr.exprs.map((part) => bindWhereExprInScope(contract, part, aliases)));
|
|
932
1036
|
},
|
|
933
1037
|
or(expr) {
|
|
934
|
-
return OrExpr.of(expr.exprs.map((part) =>
|
|
1038
|
+
return OrExpr.of(expr.exprs.map((part) => bindWhereExprInScope(contract, part, aliases)));
|
|
935
1039
|
},
|
|
936
1040
|
exists(expr) {
|
|
937
|
-
return expr.notExists ? ExistsExpr.notExists(bindSelectAst(contract, expr.subquery)) : ExistsExpr.exists(bindSelectAst(contract, expr.subquery));
|
|
1041
|
+
return expr.notExists ? ExistsExpr.notExists(bindSelectAst(contract, expr.subquery, aliases)) : ExistsExpr.exists(bindSelectAst(contract, expr.subquery, aliases));
|
|
938
1042
|
},
|
|
939
1043
|
nullCheck(expr) {
|
|
940
|
-
return expr.isNull ? NullCheckExpr.isNull(bindExpression(contract, expr.expr)) : NullCheckExpr.isNotNull(bindExpression(contract, expr.expr));
|
|
1044
|
+
return expr.isNull ? NullCheckExpr.isNull(bindExpression(contract, expr.expr, aliases)) : NullCheckExpr.isNotNull(bindExpression(contract, expr.expr, aliases));
|
|
941
1045
|
},
|
|
942
1046
|
not(expr) {
|
|
943
|
-
return new NotExpr(
|
|
1047
|
+
return new NotExpr(bindWhereExprInScope(contract, expr.expr, aliases));
|
|
944
1048
|
},
|
|
945
1049
|
rawExpr(expr) {
|
|
946
1050
|
return expr;
|
|
947
1051
|
}
|
|
948
1052
|
});
|
|
949
1053
|
}
|
|
950
|
-
function bindComparable(contract, comparable, bindingColumn,
|
|
951
|
-
if (comparable.kind === "param-ref" || bindingColumn === void 0) return comparable.kind === "param-ref" ? comparable : comparable.kind === "literal" || comparable.kind === "list" ? comparable : bindExpression(contract, comparable);
|
|
952
|
-
if (comparable.kind === "literal") return
|
|
953
|
-
if (comparable.kind === "list") return ListExpression.of(comparable.values.map((value) => value.kind === "literal" ?
|
|
954
|
-
return bindExpression(contract, comparable);
|
|
955
|
-
}
|
|
956
|
-
function
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
column: columnRef.column
|
|
1054
|
+
function bindComparable(contract, comparable, bindingColumn, aliases) {
|
|
1055
|
+
if (comparable.kind === "param-ref" || bindingColumn === void 0) return comparable.kind === "param-ref" ? comparable : comparable.kind === "literal" || comparable.kind === "list" ? comparable : bindExpression(contract, comparable, aliases);
|
|
1056
|
+
if (comparable.kind === "literal") return paramRefForAlias(contract, bindingColumn, comparable.value, aliases);
|
|
1057
|
+
if (comparable.kind === "list") return ListExpression.of(comparable.values.map((value) => value.kind === "literal" ? paramRefForAlias(contract, bindingColumn, value.value, aliases) : value));
|
|
1058
|
+
return bindExpression(contract, comparable, aliases);
|
|
1059
|
+
}
|
|
1060
|
+
function unknownColumn(alias, column) {
|
|
1061
|
+
return ormError("ORM.COLUMN_UNKNOWN", `Unknown column "${column}" in table "${alias}"`, { meta: {
|
|
1062
|
+
tableName: alias,
|
|
1063
|
+
column
|
|
961
1064
|
} });
|
|
962
|
-
const codec = codecRefForStorageColumn(contract.storage, resolved.namespaceId, columnRef.table, columnRef.column);
|
|
963
|
-
return ParamRef.of(value, codec ? { codec } : void 0);
|
|
964
1065
|
}
|
|
965
|
-
function
|
|
966
|
-
|
|
1066
|
+
function paramRefForAlias(contract, columnRef, value, aliases) {
|
|
1067
|
+
const coordinate = aliases.get(columnRef.table);
|
|
1068
|
+
if (coordinate === void 0) throw unknownColumn(columnRef.table, columnRef.column);
|
|
1069
|
+
return paramRefForTable(contract, coordinate, columnRef.table, columnRef.column, value);
|
|
1070
|
+
}
|
|
1071
|
+
function paramRefForTable(contract, coordinate, alias, column, value) {
|
|
1072
|
+
const resolved = resolveStorageTable(contract.storage, coordinate.tableName, coordinate.namespaceId);
|
|
1073
|
+
if (resolved === void 0 || !resolved.table.columns[column]) throw unknownColumn(alias, column);
|
|
1074
|
+
const codec = codecRefForStorageColumn(contract.storage, resolved.namespaceId, coordinate.tableName, column);
|
|
1075
|
+
return ParamRef.of(value, codec ? { codec } : void 0);
|
|
967
1076
|
}
|
|
968
|
-
function
|
|
969
|
-
return
|
|
1077
|
+
function paramRefForStorageColumn(contract, storage, column, value) {
|
|
1078
|
+
return paramRefForTable(contract, storage, storage.tableName, column, value);
|
|
970
1079
|
}
|
|
971
|
-
function
|
|
972
|
-
return expr.
|
|
1080
|
+
function bindExpression(contract, expr, aliases) {
|
|
1081
|
+
return expr.rewrite({ select: (ast) => bindSelectAst(contract, ast, aliases) });
|
|
973
1082
|
}
|
|
974
|
-
function
|
|
975
|
-
return
|
|
1083
|
+
function bindProjectionExpr(contract, expr, aliases) {
|
|
1084
|
+
return expr.kind === "literal" ? expr : bindExpression(contract, expr, aliases);
|
|
976
1085
|
}
|
|
977
|
-
function bindJoin(contract, join) {
|
|
978
|
-
|
|
979
|
-
return new JoinAst(join.joinType, bindFromSource(contract, join.source), join.on.kind === "eq-col-join-on" ? join.on : bindWhereExpr(contract, join.on, namespaceId), join.lateral);
|
|
1086
|
+
function bindJoin(contract, join, aliases) {
|
|
1087
|
+
return new JoinAst(join.joinType, bindFromSource(contract, join.source, aliases), join.on.kind === "eq-col-join-on" ? join.on : bindWhereExprInScope(contract, join.on, aliases), join.lateral);
|
|
980
1088
|
}
|
|
981
|
-
function bindFromSource(contract, source) {
|
|
982
|
-
if (source.kind === "table-source") return source;
|
|
983
|
-
if (source.kind === "derived-table-source") return DerivedTableSource.as(source.alias, bindSelectAst(contract, source.query));
|
|
1089
|
+
function bindFromSource(contract, source, aliases) {
|
|
1090
|
+
if (source.kind === "derived-table-source") return DerivedTableSource.as(source.alias, bindSelectAst(contract, source.query, aliases));
|
|
984
1091
|
return source;
|
|
985
1092
|
}
|
|
986
|
-
function
|
|
987
|
-
const
|
|
1093
|
+
function aliasesWithSources(outer, sources) {
|
|
1094
|
+
const aliases = new Map(outer);
|
|
1095
|
+
for (const source of sources) if (source.kind === "table-source") aliases.set(source.alias ?? source.name, {
|
|
1096
|
+
namespaceId: source.namespaceId,
|
|
1097
|
+
tableName: source.name
|
|
1098
|
+
});
|
|
1099
|
+
return aliases;
|
|
1100
|
+
}
|
|
1101
|
+
function bindSelectAst(contract, ast, outer) {
|
|
1102
|
+
const aliases = aliasesWithSources(outer, [...ast.from !== void 0 ? [ast.from] : [], ...(ast.joins ?? []).map((join) => join.source)]);
|
|
988
1103
|
return new SelectAst({
|
|
989
|
-
...ast.from !== void 0 ? { from: bindFromSource(contract, ast.from) } : {},
|
|
990
|
-
joins: ast.joins?.map((join) => bindJoin(contract, join)),
|
|
991
|
-
projection: ast.projection.map((projection) => new ProjectionItem(projection.alias, bindProjectionExpr(contract, projection.expr), projection.codec)),
|
|
992
|
-
where: ast.where ?
|
|
993
|
-
orderBy: ast.orderBy?.map((orderItem) =>
|
|
1104
|
+
...ast.from !== void 0 ? { from: bindFromSource(contract, ast.from, outer) } : {},
|
|
1105
|
+
joins: ast.joins?.map((join) => bindJoin(contract, join, aliases)),
|
|
1106
|
+
projection: ast.projection.map((projection) => new ProjectionItem(projection.alias, bindProjectionExpr(contract, projection.expr, aliases), projection.codec)),
|
|
1107
|
+
where: ast.where ? bindWhereExprInScope(contract, ast.where, aliases) : void 0,
|
|
1108
|
+
orderBy: ast.orderBy?.map((orderItem) => orderItem.withExpr(bindExpression(contract, orderItem.expr, aliases))),
|
|
994
1109
|
distinct: ast.distinct,
|
|
995
|
-
distinctOn: ast.distinctOn?.map((expr) => bindExpression(contract, expr)),
|
|
996
|
-
groupBy: ast.groupBy?.map((expr) => bindExpression(contract, expr)),
|
|
997
|
-
having: ast.having ?
|
|
1110
|
+
distinctOn: ast.distinctOn?.map((expr) => bindExpression(contract, expr, aliases)),
|
|
1111
|
+
groupBy: ast.groupBy?.map((expr) => bindExpression(contract, expr, aliases)),
|
|
1112
|
+
having: ast.having ? bindWhereExprInScope(contract, ast.having, aliases) : void 0,
|
|
998
1113
|
limit: ast.limit,
|
|
999
1114
|
offset: ast.offset,
|
|
1000
1115
|
locking: ast.locking,
|
|
@@ -1006,14 +1121,14 @@ function combineWhereExprs(filters) {
|
|
|
1006
1121
|
if (filters.length === 1) return filters[0];
|
|
1007
1122
|
return AndExpr.of(filters);
|
|
1008
1123
|
}
|
|
1009
|
-
function createBoundaryExpr(
|
|
1010
|
-
return new BinaryExpr(entry.direction === "asc" ? "gt" : "lt",
|
|
1124
|
+
function createBoundaryExpr(contract, table, entry) {
|
|
1125
|
+
return new BinaryExpr(entry.direction === "asc" ? "gt" : "lt", table.column(entry.column), paramRefForStorageColumn(contract, table.storage, entry.column, entry.value));
|
|
1011
1126
|
}
|
|
1012
|
-
function buildLexicographicCursorWhere(
|
|
1127
|
+
function buildLexicographicCursorWhere(contract, table, entries) {
|
|
1013
1128
|
const branches = entries.map((entry, index) => {
|
|
1014
1129
|
const branchExprs = [];
|
|
1015
|
-
for (const prefixEntry of entries.slice(0, index)) branchExprs.push(BinaryExpr.eq(
|
|
1016
|
-
branchExprs.push(createBoundaryExpr(
|
|
1130
|
+
for (const prefixEntry of entries.slice(0, index)) branchExprs.push(BinaryExpr.eq(table.column(prefixEntry.column), paramRefForStorageColumn(contract, table.storage, prefixEntry.column, prefixEntry.value)));
|
|
1131
|
+
branchExprs.push(createBoundaryExpr(contract, table, entry));
|
|
1017
1132
|
if (branchExprs.length === 1) {
|
|
1018
1133
|
const branch = branchExprs[0];
|
|
1019
1134
|
assertDefined(branch, "cursor branch contains its boundary expression");
|
|
@@ -1028,7 +1143,7 @@ function buildLexicographicCursorWhere(tableName, entries) {
|
|
|
1028
1143
|
}
|
|
1029
1144
|
return OrExpr.of(branches);
|
|
1030
1145
|
}
|
|
1031
|
-
function buildCursorWhere(
|
|
1146
|
+
function buildCursorWhere(contract, table, orderBy, cursor) {
|
|
1032
1147
|
if (!cursor || !orderBy || orderBy.length === 0) return;
|
|
1033
1148
|
assertCursorCompatibleOrder(orderBy);
|
|
1034
1149
|
const entries = [];
|
|
@@ -1044,28 +1159,12 @@ function buildCursorWhere(tableName, orderBy, cursor) {
|
|
|
1044
1159
|
});
|
|
1045
1160
|
}
|
|
1046
1161
|
const firstEntry = entries[0];
|
|
1047
|
-
if (entries.length === 1 && firstEntry !== void 0) return createBoundaryExpr(
|
|
1048
|
-
return buildLexicographicCursorWhere(
|
|
1049
|
-
}
|
|
1050
|
-
function createTableRefRemapper$1(fromTable, toTable) {
|
|
1051
|
-
return {
|
|
1052
|
-
columnRef: (col) => col.table === fromTable ? ColumnRef.of(toTable, col.column) : col,
|
|
1053
|
-
tableSource: (source) => {
|
|
1054
|
-
if (source.alias === fromTable) return TableSource.named(source.name, toTable, source.namespaceId);
|
|
1055
|
-
if (!source.alias && source.name === fromTable) return TableSource.named(source.name, toTable, source.namespaceId);
|
|
1056
|
-
return source;
|
|
1057
|
-
},
|
|
1058
|
-
eqColJoinOn: (on) => EqColJoinOn.of(on.left.table === fromTable ? ColumnRef.of(toTable, on.left.column) : on.left, on.right.table === fromTable ? ColumnRef.of(toTable, on.right.column) : on.right)
|
|
1059
|
-
};
|
|
1162
|
+
if (entries.length === 1 && firstEntry !== void 0) return createBoundaryExpr(contract, table, firstEntry);
|
|
1163
|
+
return buildLexicographicCursorWhere(contract, table, entries);
|
|
1060
1164
|
}
|
|
1061
|
-
function buildStateWhere(contract,
|
|
1062
|
-
const
|
|
1063
|
-
|
|
1064
|
-
const boundFilters = state.filters.map((filter) => bindWhereExpr(contract, filter, options?.namespaceId));
|
|
1065
|
-
const remappedFilters = filterTableName && filterTableName !== tableName ? boundFilters.map((filter) => filter.rewrite(createTableRefRemapper$1(filterTableName, tableName))) : boundFilters;
|
|
1066
|
-
const boundCursorWhere = cursorWhere ? bindWhereExpr(contract, cursorWhere, options?.namespaceId) : void 0;
|
|
1067
|
-
const remappedCursorWhere = boundCursorWhere && filterTableName && filterTableName !== tableName ? boundCursorWhere.rewrite(createTableRefRemapper$1(filterTableName, tableName)) : boundCursorWhere;
|
|
1068
|
-
return combineWhereExprs(remappedCursorWhere ? [...remappedFilters, remappedCursorWhere] : remappedFilters);
|
|
1165
|
+
function buildStateWhere(contract, state) {
|
|
1166
|
+
const cursorWhere = buildCursorWhere(contract, state.tables.root, state.orderBy, state.cursor);
|
|
1167
|
+
return combineWhereExprs(cursorWhere ? [...state.filters, cursorWhere] : state.filters);
|
|
1069
1168
|
}
|
|
1070
1169
|
/**
|
|
1071
1170
|
* Wrap a base SELECT in a `ROW_NUMBER() OVER (PARTITION BY … ORDER BY …) = 1`
|
|
@@ -1098,32 +1197,33 @@ function wrapWithRowNumberDedup(options) {
|
|
|
1098
1197
|
}
|
|
1099
1198
|
/**
|
|
1100
1199
|
* FROM source + WHERE for `state.distinct`: wraps in a `ROW_NUMBER`-ranked
|
|
1101
|
-
* derived table aliased back to
|
|
1200
|
+
* derived table aliased back to the root alias, so callers need no rewriting.
|
|
1102
1201
|
*/
|
|
1103
|
-
function buildDedupedTableSource(contract,
|
|
1202
|
+
function buildDedupedTableSource(contract, state, where, wrapProjection, joins) {
|
|
1203
|
+
const { root } = state.tables;
|
|
1104
1204
|
if (!hasEntries(state.distinct)) return {
|
|
1105
|
-
source:
|
|
1205
|
+
source: root.tableSource(contract),
|
|
1106
1206
|
where
|
|
1107
1207
|
};
|
|
1108
|
-
const distinctColumnRefs = state.distinct.map((column) =>
|
|
1208
|
+
const distinctColumnRefs = state.distinct.map((column) => root.column(column));
|
|
1109
1209
|
const rankingOrderBy = hasEntries(state.orderBy) ? state.orderBy : distinctColumnRefs.map((expr) => OrderByItem.asc(expr));
|
|
1110
|
-
let inner = SelectAst.from(
|
|
1210
|
+
let inner = SelectAst.from(root.tableSource(contract)).withProjection([...wrapProjection, ProjectionItem.of("__prisma_distinct_rn", WindowFuncExpr.rowNumber({
|
|
1111
1211
|
partitionBy: distinctColumnRefs,
|
|
1112
1212
|
orderBy: rankingOrderBy
|
|
1113
1213
|
}))]);
|
|
1114
1214
|
if (joins && joins.length > 0) inner = inner.withJoins(joins);
|
|
1115
1215
|
if (where) inner = inner.withWhere(where);
|
|
1116
1216
|
return {
|
|
1117
|
-
source: DerivedTableSource.as(
|
|
1118
|
-
where: BinaryExpr.eq(
|
|
1217
|
+
source: DerivedTableSource.as(root.alias, inner),
|
|
1218
|
+
where: BinaryExpr.eq(root.column("__prisma_distinct_rn"), LiteralExpr.of(1))
|
|
1119
1219
|
};
|
|
1120
1220
|
}
|
|
1121
|
-
function buildPrimaryKeyJoinOn(
|
|
1221
|
+
function buildPrimaryKeyJoinOn(left, right, primaryKeyColumns) {
|
|
1122
1222
|
const [firstColumn] = primaryKeyColumns;
|
|
1123
|
-
if (primaryKeyColumns.length === 1 && firstColumn !== void 0) return EqColJoinOn.of(
|
|
1124
|
-
return AndExpr.of(primaryKeyColumns.map((column) => BinaryExpr.eq(
|
|
1223
|
+
if (primaryKeyColumns.length === 1 && firstColumn !== void 0) return EqColJoinOn.of(left.column(firstColumn), right.column(firstColumn));
|
|
1224
|
+
return AndExpr.of(primaryKeyColumns.map((column) => BinaryExpr.eq(left.column(column), right.column(column))));
|
|
1125
1225
|
}
|
|
1126
|
-
function buildMtiJoins(contract,
|
|
1226
|
+
function buildMtiJoins(contract, tables, polyInfo, variantName, selectedColumnsByVariant) {
|
|
1127
1227
|
const joins = [];
|
|
1128
1228
|
const projection = [];
|
|
1129
1229
|
const variantsToJoin = variantName ? polyInfo.mtiVariants.filter((v) => v.modelName === variantName) : polyInfo.mtiVariants;
|
|
@@ -1131,19 +1231,19 @@ function buildMtiJoins(contract, namespaceId, polyInfo, variantName, selectedCol
|
|
|
1131
1231
|
joins,
|
|
1132
1232
|
projection
|
|
1133
1233
|
};
|
|
1134
|
-
const
|
|
1234
|
+
const { root } = tables;
|
|
1235
|
+
const pkColumns = resolvePrimaryKeyColumns(contract, root.storage.namespaceId, root.storage.tableName);
|
|
1135
1236
|
for (const variant of variantsToJoin) {
|
|
1136
|
-
const
|
|
1137
|
-
const joinOn = buildPrimaryKeyJoinOn(
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
const variantColumns = getColumnsReadOnTable(contract, namespaceId, variant.modelName,
|
|
1141
|
-
const selectedVariantColumns =
|
|
1237
|
+
const variantTable = requireVariantTable(tables, variant.modelName);
|
|
1238
|
+
const joinOn = buildPrimaryKeyJoinOn(root, variantTable, pkColumns);
|
|
1239
|
+
joins.push(variantName ? JoinAst.inner(variantTable.tableSource(contract), joinOn) : JoinAst.left(variantTable.tableSource(contract), joinOn));
|
|
1240
|
+
const { namespaceId, tableName } = variantTable.storage;
|
|
1241
|
+
const variantColumns = getColumnsReadOnTable(contract, namespaceId, variant.modelName, tableName);
|
|
1242
|
+
const selectedVariantColumns = selectedColumnsByVariant?.get(variant.modelName);
|
|
1142
1243
|
for (const col of variantColumns) {
|
|
1143
1244
|
if (pkColumns.includes(col)) continue;
|
|
1144
|
-
if (
|
|
1145
|
-
|
|
1146
|
-
projection.push(ProjectionItem.of(alias, ColumnRef.of(variant.table, col), codecRefForStorageColumn(contract.storage, namespaceId, variant.table, col)));
|
|
1245
|
+
if (selectedColumnsByVariant !== void 0 && selectedVariantColumns?.has(col) !== true) continue;
|
|
1246
|
+
projection.push(ProjectionItem.of(variantColumnLabel(variantTable, col), variantTable.column(col), codecRefForStorageColumn(contract.storage, namespaceId, tableName, col)));
|
|
1147
1247
|
}
|
|
1148
1248
|
}
|
|
1149
1249
|
return {
|
|
@@ -1155,30 +1255,31 @@ function hasEntries(value) {
|
|
|
1155
1255
|
return value !== void 0 && value.length > 0;
|
|
1156
1256
|
}
|
|
1157
1257
|
/**
|
|
1158
|
-
* The rows an aggregate reduces over, one SELECT aliased to
|
|
1258
|
+
* The rows an aggregate reduces over, one SELECT aliased to the root alias — an
|
|
1159
1259
|
* aggregate has no outer level of its own, so where/joins/distinct/orderBy/
|
|
1160
1260
|
* limit/offset all have to live in this one wrap.
|
|
1161
1261
|
*/
|
|
1162
|
-
function buildAggregateInput(contract,
|
|
1163
|
-
const
|
|
1164
|
-
const
|
|
1165
|
-
const
|
|
1166
|
-
const
|
|
1167
|
-
const
|
|
1262
|
+
function buildAggregateInput(contract, state, modelName, projection) {
|
|
1263
|
+
const { root } = state.tables;
|
|
1264
|
+
const polyInfo = modelName ? resolvePolymorphismInfo(contract, root.storage.namespaceId, modelName) : void 0;
|
|
1265
|
+
const variantJoins = polyInfo && polyInfo.mtiVariants.length > 0 ? buildMtiJoins(contract, state.tables, polyInfo, state.variantName, void 0).joins : [];
|
|
1266
|
+
const where = buildStateWhere(contract, state);
|
|
1267
|
+
const hiddenOrders = hasEntries(state.distinct) ? projectExpressionOrders(root, state.orderBy) : void 0;
|
|
1268
|
+
const { source, where: effectiveWhere } = buildDedupedTableSource(contract, state, where, [...projection, ...hiddenOrders?.projection ?? []], variantJoins);
|
|
1168
1269
|
let inner = SelectAst.from(source).withProjection(projection);
|
|
1169
1270
|
if (!hasEntries(state.distinct) && variantJoins.length > 0) inner = inner.withJoins(variantJoins);
|
|
1170
1271
|
if (effectiveWhere) inner = inner.withWhere(effectiveWhere);
|
|
1171
|
-
if (hasEntries(state.distinctOn)) inner = inner.withDistinctOn(state.distinctOn.map((column) =>
|
|
1272
|
+
if (hasEntries(state.distinctOn)) inner = inner.withDistinctOn(state.distinctOn.map((column) => root.column(column)));
|
|
1172
1273
|
const orderBy = hiddenOrders?.orderBy ?? state.orderBy;
|
|
1173
1274
|
if (hasEntries(orderBy)) inner = inner.withOrderBy(orderBy);
|
|
1174
1275
|
if (state.limit !== void 0) inner = inner.withLimit(state.limit);
|
|
1175
1276
|
if (state.offset !== void 0) inner = inner.withOffset(state.offset);
|
|
1176
|
-
return { source: DerivedTableSource.as(
|
|
1277
|
+
return { source: DerivedTableSource.as(root.alias, inner) };
|
|
1177
1278
|
}
|
|
1178
1279
|
/**
|
|
1179
1280
|
* The dedup wrap exposes only its projection, so an order over an expression (a relation order, a count, an operation result) cannot be evaluated above it. Each such order is projected inside the wrap as a hidden `__order_N` column and the outer order reads that column.
|
|
1180
1281
|
*/
|
|
1181
|
-
function projectExpressionOrders(
|
|
1282
|
+
function projectExpressionOrders(root, orderBy) {
|
|
1182
1283
|
const projection = [];
|
|
1183
1284
|
return {
|
|
1184
1285
|
projection,
|
|
@@ -1186,7 +1287,7 @@ function projectExpressionOrders(tableName, orderBy) {
|
|
|
1186
1287
|
if (item.expr.kind === "column-ref") return item;
|
|
1187
1288
|
const alias = `__order_${index}`;
|
|
1188
1289
|
projection.push(ProjectionItem.of(alias, item.expr));
|
|
1189
|
-
return item.withExpr(
|
|
1290
|
+
return item.withExpr(root.column(alias));
|
|
1190
1291
|
})
|
|
1191
1292
|
};
|
|
1192
1293
|
}
|
|
@@ -1199,8 +1300,9 @@ function predicateComparison(op, left, right) {
|
|
|
1199
1300
|
function predicateExpression(value) {
|
|
1200
1301
|
if (isExpression(value)) return value.buildAst();
|
|
1201
1302
|
}
|
|
1202
|
-
function emptyState() {
|
|
1303
|
+
function emptyState(tables) {
|
|
1203
1304
|
return {
|
|
1305
|
+
tables,
|
|
1204
1306
|
filters: [],
|
|
1205
1307
|
includes: [],
|
|
1206
1308
|
orderBy: void 0,
|
|
@@ -1300,7 +1402,8 @@ const COMPARISON_METHODS_META = {
|
|
|
1300
1402
|
create: (left) => () => NullCheckExpr.isNotNull(left)
|
|
1301
1403
|
}
|
|
1302
1404
|
};
|
|
1303
|
-
function toAggregateProjection(contract, aggregates,
|
|
1405
|
+
function toAggregateProjection(contract, aggregates, root, selector) {
|
|
1406
|
+
const { namespaceId, tableName } = root.storage;
|
|
1304
1407
|
const { codec, input: inputCodec, lower } = resolveAggregate({
|
|
1305
1408
|
aggregates,
|
|
1306
1409
|
contract,
|
|
@@ -1309,7 +1412,7 @@ function toAggregateProjection(contract, aggregates, namespaceId, tableName, sel
|
|
|
1309
1412
|
fn: selector.fn,
|
|
1310
1413
|
column: selector.column
|
|
1311
1414
|
});
|
|
1312
|
-
const inputExpr = selector.column === void 0 ? void 0 :
|
|
1415
|
+
const inputExpr = selector.column === void 0 ? void 0 : root.column(selector.column);
|
|
1313
1416
|
return {
|
|
1314
1417
|
expr: lower !== void 0 ? lower({
|
|
1315
1418
|
expr: inputExpr,
|
|
@@ -1383,14 +1486,16 @@ function validateGroupedHavingExpr(expr) {
|
|
|
1383
1486
|
rawExpr: rejectHavingExpr
|
|
1384
1487
|
});
|
|
1385
1488
|
}
|
|
1386
|
-
function aggregateInputColumns(
|
|
1489
|
+
function aggregateInputColumns(root, entries, orderBy, groupByColumns = []) {
|
|
1387
1490
|
const columns = new Set(groupByColumns);
|
|
1388
1491
|
for (const [, selector] of entries) if (selector.column !== void 0) columns.add(selector.column);
|
|
1389
1492
|
for (const item of orderBy ?? []) if (item.expr.kind === "column-ref") columns.add(item.expr.column);
|
|
1390
1493
|
if (columns.size === 0) return [ProjectionItem.of("__row", LiteralExpr.of(1))];
|
|
1391
|
-
return Array.from(columns, (column) => ProjectionItem.of(column,
|
|
1494
|
+
return Array.from(columns, (column) => ProjectionItem.of(column, root.column(column)));
|
|
1392
1495
|
}
|
|
1393
|
-
function compileAggregate(contract, aggregates,
|
|
1496
|
+
function compileAggregate(contract, aggregates, state, aggregateSpec, modelName) {
|
|
1497
|
+
const { root } = state.tables;
|
|
1498
|
+
const { namespaceId, tableName } = root.storage;
|
|
1394
1499
|
const entries = Object.entries(aggregateSpec);
|
|
1395
1500
|
if (entries.length === 0) throw ormError("ORM.AGGREGATE_SELECTOR_MISSING", "aggregate() requires at least one aggregation selector", { meta: {
|
|
1396
1501
|
method: "aggregate",
|
|
@@ -1404,9 +1509,9 @@ function compileAggregate(contract, aggregates, namespaceId, tableName, state, a
|
|
|
1404
1509
|
const hasPagination = state.limit !== void 0 || state.offset !== void 0;
|
|
1405
1510
|
const hasDistinct = state.distinct !== void 0 && state.distinct.length > 0 || state.distinctOn !== void 0 && state.distinctOn.length > 0;
|
|
1406
1511
|
if (hasPagination || hasDistinct) {
|
|
1407
|
-
const { source } = buildAggregateInput(contract,
|
|
1512
|
+
const { source } = buildAggregateInput(contract, state, modelName, aggregateInputColumns(root, entries, state.orderBy));
|
|
1408
1513
|
const projection = entries.map(([alias, selector]) => {
|
|
1409
|
-
const { expr, codec } = toAggregateProjection(contract, aggregates,
|
|
1514
|
+
const { expr, codec } = toAggregateProjection(contract, aggregates, root, selector);
|
|
1410
1515
|
return ProjectionItem.of(alias, expr, codec);
|
|
1411
1516
|
});
|
|
1412
1517
|
const ast = SelectAst.from(source).withProjection(projection);
|
|
@@ -1414,19 +1519,21 @@ function compileAggregate(contract, aggregates, namespaceId, tableName, state, a
|
|
|
1414
1519
|
return buildOrmQueryPlan(contract, ast, params);
|
|
1415
1520
|
}
|
|
1416
1521
|
const polyInfo = modelName ? resolvePolymorphismInfo(contract, namespaceId, modelName) : void 0;
|
|
1417
|
-
const variantJoins = polyInfo && polyInfo.mtiVariants.length > 0 ? buildMtiJoins(contract,
|
|
1418
|
-
const where = buildStateWhere(contract,
|
|
1522
|
+
const variantJoins = polyInfo && polyInfo.mtiVariants.length > 0 ? buildMtiJoins(contract, state.tables, polyInfo, state.variantName, void 0).joins : [];
|
|
1523
|
+
const where = buildStateWhere(contract, state);
|
|
1419
1524
|
const projection = entries.map(([alias, selector]) => {
|
|
1420
|
-
const { expr, codec } = toAggregateProjection(contract, aggregates,
|
|
1525
|
+
const { expr, codec } = toAggregateProjection(contract, aggregates, root, selector);
|
|
1421
1526
|
return ProjectionItem.of(alias, expr, codec);
|
|
1422
1527
|
});
|
|
1423
|
-
let ast = SelectAst.from(
|
|
1528
|
+
let ast = SelectAst.from(root.tableSource(contract)).withProjection(projection);
|
|
1424
1529
|
if (variantJoins.length > 0) ast = ast.withJoins(variantJoins);
|
|
1425
1530
|
if (where) ast = ast.withWhere(where);
|
|
1426
1531
|
const { params } = deriveParamsFromAst(ast);
|
|
1427
1532
|
return buildOrmQueryPlan(contract, ast, params);
|
|
1428
1533
|
}
|
|
1429
|
-
function compileGroupedAggregate(contract, aggregates,
|
|
1534
|
+
function compileGroupedAggregate(contract, aggregates, preGroupState, groupByColumns, aggregateSpec, havingExpr, modelName, postGroup = emptyGroupPagingState()) {
|
|
1535
|
+
const { root } = preGroupState.tables;
|
|
1536
|
+
const { namespaceId, tableName } = root.storage;
|
|
1430
1537
|
if (groupByColumns.length === 0) throw ormError("ORM.GROUP_BY_FIELD_MISSING", "groupBy() requires at least one field", { meta: {
|
|
1431
1538
|
namespaceId,
|
|
1432
1539
|
tableName
|
|
@@ -1441,8 +1548,8 @@ function compileGroupedAggregate(contract, aggregates, namespaceId, tableName, p
|
|
|
1441
1548
|
assertDistinctOnCapability(contract, "distinctOn");
|
|
1442
1549
|
assertDistinctOnCompatibleOrder(preGroupState.orderBy, preGroupState.distinctOn.length);
|
|
1443
1550
|
}
|
|
1444
|
-
const projection = [...groupByColumns.map((column) => ProjectionItem.of(column,
|
|
1445
|
-
const { expr, codec } = toAggregateProjection(contract, aggregates,
|
|
1551
|
+
const projection = [...groupByColumns.map((column) => ProjectionItem.of(column, root.column(column), codecRefForStorageColumn(contract.storage, namespaceId, tableName, column))), ...entries.map(([alias, selector]) => {
|
|
1552
|
+
const { expr, codec } = toAggregateProjection(contract, aggregates, root, selector);
|
|
1446
1553
|
return ProjectionItem.of(alias, expr, codec);
|
|
1447
1554
|
})];
|
|
1448
1555
|
const hasPagination = preGroupState.limit !== void 0 || preGroupState.offset !== void 0;
|
|
@@ -1450,14 +1557,15 @@ function compileGroupedAggregate(contract, aggregates, namespaceId, tableName, p
|
|
|
1450
1557
|
const needsInputSelect = hasPagination || hasDistinct;
|
|
1451
1558
|
let ast;
|
|
1452
1559
|
if (needsInputSelect) {
|
|
1453
|
-
const { source } = buildAggregateInput(contract,
|
|
1454
|
-
ast = SelectAst.from(source).withProjection(projection).withGroupBy(groupByColumns.map((column) =>
|
|
1560
|
+
const { source } = buildAggregateInput(contract, preGroupState, modelName, aggregateInputColumns(root, entries, preGroupState.orderBy, groupByColumns));
|
|
1561
|
+
ast = SelectAst.from(source).withProjection(projection).withGroupBy(groupByColumns.map((column) => root.column(column)));
|
|
1455
1562
|
} else {
|
|
1456
1563
|
const polyInfo = modelName ? resolvePolymorphismInfo(contract, namespaceId, modelName) : void 0;
|
|
1457
|
-
const
|
|
1458
|
-
|
|
1564
|
+
const { tables, variantName } = preGroupState;
|
|
1565
|
+
const variantJoins = polyInfo && polyInfo.mtiVariants.length > 0 ? buildMtiJoins(contract, tables, polyInfo, variantName, void 0).joins : [];
|
|
1566
|
+
ast = SelectAst.from(root.tableSource(contract)).withProjection(projection).withGroupBy(groupByColumns.map((column) => root.column(column)));
|
|
1459
1567
|
if (variantJoins.length > 0) ast = ast.withJoins(variantJoins);
|
|
1460
|
-
const where = buildStateWhere(contract,
|
|
1568
|
+
const where = buildStateWhere(contract, preGroupState);
|
|
1461
1569
|
if (where) ast = ast.withWhere(where);
|
|
1462
1570
|
}
|
|
1463
1571
|
if (havingExpr) ast = ast.withHaving(validateGroupedHavingExpr(havingExpr));
|
|
@@ -1467,8 +1575,15 @@ function compileGroupedAggregate(contract, aggregates, namespaceId, tableName, p
|
|
|
1467
1575
|
const { params } = deriveParamsFromAst(ast);
|
|
1468
1576
|
return buildOrmQueryPlan(contract, ast, params);
|
|
1469
1577
|
}
|
|
1470
|
-
function
|
|
1471
|
-
return (
|
|
1578
|
+
function aliasTarget(namespaceId, tableName) {
|
|
1579
|
+
return createTableScope().aliasTable({
|
|
1580
|
+
namespaceId,
|
|
1581
|
+
tableName
|
|
1582
|
+
});
|
|
1583
|
+
}
|
|
1584
|
+
function buildReturningColumns(contract, modelName, target, returningColumns) {
|
|
1585
|
+
const { namespaceId, tableName } = target.storage;
|
|
1586
|
+
return (returningColumns && returningColumns.length > 0 ? [...returningColumns] : getColumnsReadOnTable(contract, namespaceId, modelName, tableName)).map((column) => ProjectionItem.of(column, target.column(column), codecRefForStorageColumn(contract.storage, namespaceId, tableName, column)));
|
|
1472
1587
|
}
|
|
1473
1588
|
function toParamAssignments(contract, namespaceId, tableName, values) {
|
|
1474
1589
|
const assignments = {};
|
|
@@ -1519,20 +1634,22 @@ function normalizeInsertRows(contract, namespaceId, tableName, rows) {
|
|
|
1519
1634
|
return normalizedRow;
|
|
1520
1635
|
}) };
|
|
1521
1636
|
}
|
|
1522
|
-
function conflictSkipClause(
|
|
1637
|
+
function conflictSkipClause(target, conflictSkip) {
|
|
1523
1638
|
if (!conflictSkip) return void 0;
|
|
1524
1639
|
if (conflictSkip.columns.length === 0) return InsertOnConflict.doNothing();
|
|
1525
|
-
return InsertOnConflict.on(conflictSkip.columns.map((column) =>
|
|
1640
|
+
return InsertOnConflict.on(conflictSkip.columns.map((column) => target.column(column))).doNothing();
|
|
1526
1641
|
}
|
|
1527
1642
|
function compileInsertReturning(contract, namespaceId, modelName, tableName, rows, returningColumns, conflictSkip) {
|
|
1643
|
+
const target = aliasTarget(namespaceId, tableName);
|
|
1528
1644
|
const { rows: normalizedRows } = normalizeInsertRows(contract, namespaceId, tableName, rows);
|
|
1529
|
-
const ast = InsertAst.into(
|
|
1645
|
+
const ast = InsertAst.into(target.tableSource(contract)).withRows(normalizedRows).withOnConflict(conflictSkipClause(target, conflictSkip)).withReturning(buildReturningColumns(contract, modelName, target, returningColumns));
|
|
1530
1646
|
const { params } = deriveParamsFromAst(ast);
|
|
1531
1647
|
return buildOrmQueryPlan(contract, ast, params);
|
|
1532
1648
|
}
|
|
1533
1649
|
function compileInsertCount(contract, namespaceId, tableName, rows, conflictSkip) {
|
|
1650
|
+
const target = aliasTarget(namespaceId, tableName);
|
|
1534
1651
|
const { rows: normalizedRows } = normalizeInsertRows(contract, namespaceId, tableName, rows);
|
|
1535
|
-
const ast = InsertAst.into(
|
|
1652
|
+
const ast = InsertAst.into(target.tableSource(contract)).withRows(normalizedRows).withOnConflict(conflictSkipClause(target, conflictSkip));
|
|
1536
1653
|
const { params } = deriveParamsFromAst(ast);
|
|
1537
1654
|
return buildOrmQueryPlan(contract, ast, params);
|
|
1538
1655
|
}
|
|
@@ -1541,29 +1658,14 @@ function stripUndefinedValues(row) {
|
|
|
1541
1658
|
for (const [key, value] of Object.entries(row)) if (value !== void 0) result[key] = value;
|
|
1542
1659
|
return result;
|
|
1543
1660
|
}
|
|
1544
|
-
function
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
eqColJoinOn: (on) => EqColJoinOn.of(on.left.table === fromTable ? ColumnRef.of(toTable, on.left.column) : on.left, on.right.table === fromTable ? ColumnRef.of(toTable, on.right.column) : on.right)
|
|
1553
|
-
};
|
|
1554
|
-
}
|
|
1555
|
-
function buildCountMutationWhere(contract, namespaceId, tableName, filters, variantName, modelName) {
|
|
1556
|
-
if (!variantName || !modelName) return combineWhereExprs(filters);
|
|
1557
|
-
const polyInfo = resolvePolymorphismInfo(contract, namespaceId, modelName);
|
|
1558
|
-
const variant = polyInfo?.variants.get(variantName);
|
|
1559
|
-
if (!polyInfo || !variant || variant.strategy !== "mti") return combineWhereExprs(filters);
|
|
1560
|
-
const pkColumns = resolvePrimaryKeyColumns(contract, namespaceId, tableName);
|
|
1561
|
-
const baseTableRef = `${tableName}__write_filter`;
|
|
1562
|
-
const remapper = createTableRefRemapper(tableName, baseTableRef);
|
|
1563
|
-
const innerFilters = filters.map((filter) => filter.rewrite(remapper));
|
|
1564
|
-
const where = combineWhereExprs([...pkColumns.map((column) => BinaryExpr.eq(ColumnRef.of(baseTableRef, column), ColumnRef.of(tableName, column))), ...innerFilters]);
|
|
1565
|
-
const joinOn = buildPrimaryKeyJoinOn(baseTableRef, variant.table, pkColumns);
|
|
1566
|
-
let subquery = SelectAst.from(TableSource.named(tableName, baseTableRef, namespaceId)).withProjection(pkColumns.map((column) => ProjectionItem.of(column, ColumnRef.of(baseTableRef, column)))).withJoins([JoinAst.inner(tableSourceForContract(contract, namespaceId, variant.table), joinOn)]);
|
|
1661
|
+
function buildCountMutationWhere(contract, tables, filters, variantName) {
|
|
1662
|
+
const variantTable = variantName === void 0 ? void 0 : tables.variants.get(variantName);
|
|
1663
|
+
if (variantTable === void 0) return combineWhereExprs(filters);
|
|
1664
|
+
const { root } = tables;
|
|
1665
|
+
const pkColumns = resolvePrimaryKeyColumns(contract, root.storage.namespaceId, root.storage.tableName);
|
|
1666
|
+
const rootCopy = tables.scope.copy().aliasTable(root.storage);
|
|
1667
|
+
const where = combineWhereExprs([...pkColumns.map((column) => BinaryExpr.eq(rootCopy.column(column), root.column(column))), ...filters]);
|
|
1668
|
+
let subquery = SelectAst.from(rootCopy.tableSource(contract)).withProjection(pkColumns.map((column) => ProjectionItem.of(column, rootCopy.column(column)))).withJoins([JoinAst.inner(variantTable.tableSource(contract), buildPrimaryKeyJoinOn(rootCopy, variantTable, pkColumns))]);
|
|
1567
1669
|
if (where) subquery = subquery.withWhere(where);
|
|
1568
1670
|
return ExistsExpr.exists(subquery);
|
|
1569
1671
|
}
|
|
@@ -1602,37 +1704,44 @@ function compileInsertCountSplit(contract, namespaceId, tableName, rows, conflic
|
|
|
1602
1704
|
function compileUpsertReturning(contract, namespaceId, modelName, tableName, createValues, updateValues, conflictColumns, returningColumns) {
|
|
1603
1705
|
const createAssignments = toParamAssignments(contract, namespaceId, tableName, createValues);
|
|
1604
1706
|
const updateAssignments = Object.keys(updateValues).length > 0 ? toParamAssignments(contract, namespaceId, tableName, updateValues) : void 0;
|
|
1605
|
-
const
|
|
1606
|
-
const
|
|
1707
|
+
const target = aliasTarget(namespaceId, tableName);
|
|
1708
|
+
const conflictTarget = InsertOnConflict.on(conflictColumns.map((column) => target.column(column)));
|
|
1709
|
+
const onConflict = updateAssignments ? conflictTarget.doUpdateSet(updateAssignments.assignments) : conflictTarget.doNothing();
|
|
1710
|
+
const ast = InsertAst.into(target.tableSource(contract)).withRows([createAssignments.assignments]).withOnConflict(onConflict).withReturning(buildReturningColumns(contract, modelName, target, returningColumns));
|
|
1607
1711
|
const { params } = deriveParamsFromAst(ast);
|
|
1608
1712
|
return buildOrmQueryPlan(contract, ast, params);
|
|
1609
1713
|
}
|
|
1610
|
-
function compileUpdateReturning(contract,
|
|
1714
|
+
function compileUpdateReturning(contract, modelName, tables, setValues, filters, returningColumns) {
|
|
1715
|
+
const { root } = tables;
|
|
1716
|
+
const { namespaceId, tableName } = root.storage;
|
|
1611
1717
|
const where = combineWhereExprs(filters);
|
|
1612
1718
|
const { assignments } = toParamAssignments(contract, namespaceId, tableName, setValues);
|
|
1613
|
-
let ast = UpdateAst.table(
|
|
1719
|
+
let ast = UpdateAst.table(root.tableSource(contract)).withSet(assignments).withReturning(buildReturningColumns(contract, modelName, root, returningColumns));
|
|
1614
1720
|
if (where) ast = ast.withWhere(where);
|
|
1615
1721
|
const { params } = deriveParamsFromAst(ast);
|
|
1616
1722
|
return buildOrmQueryPlan(contract, ast, params);
|
|
1617
1723
|
}
|
|
1618
|
-
function compileUpdateCount(contract,
|
|
1619
|
-
const
|
|
1724
|
+
function compileUpdateCount(contract, tables, setValues, filters, variantName) {
|
|
1725
|
+
const { root } = tables;
|
|
1726
|
+
const { namespaceId, tableName } = root.storage;
|
|
1727
|
+
const where = buildCountMutationWhere(contract, tables, filters, variantName);
|
|
1620
1728
|
const { assignments } = toParamAssignments(contract, namespaceId, tableName, setValues);
|
|
1621
|
-
let ast = UpdateAst.table(
|
|
1729
|
+
let ast = UpdateAst.table(root.tableSource(contract)).withSet(assignments);
|
|
1622
1730
|
if (where) ast = ast.withWhere(where);
|
|
1623
1731
|
const { params } = deriveParamsFromAst(ast);
|
|
1624
1732
|
return buildOrmQueryPlan(contract, ast, params);
|
|
1625
1733
|
}
|
|
1626
|
-
function compileDeleteReturning(contract,
|
|
1734
|
+
function compileDeleteReturning(contract, modelName, tables, filters, returningColumns) {
|
|
1735
|
+
const { root } = tables;
|
|
1627
1736
|
const where = combineWhereExprs(filters);
|
|
1628
|
-
let ast = DeleteAst.from(
|
|
1737
|
+
let ast = DeleteAst.from(root.tableSource(contract)).withReturning(buildReturningColumns(contract, modelName, root, returningColumns));
|
|
1629
1738
|
if (where) ast = ast.withWhere(where);
|
|
1630
1739
|
const { params } = deriveParamsFromAst(ast);
|
|
1631
1740
|
return buildOrmQueryPlan(contract, ast, params);
|
|
1632
1741
|
}
|
|
1633
|
-
function compileDeleteCount(contract,
|
|
1634
|
-
const where = buildCountMutationWhere(contract,
|
|
1635
|
-
let ast = DeleteAst.from(
|
|
1742
|
+
function compileDeleteCount(contract, tables, filters, variantName) {
|
|
1743
|
+
const where = buildCountMutationWhere(contract, tables, filters, variantName);
|
|
1744
|
+
let ast = DeleteAst.from(tables.root.tableSource(contract));
|
|
1636
1745
|
if (where) ast = ast.withWhere(where);
|
|
1637
1746
|
const { params } = deriveParamsFromAst(ast);
|
|
1638
1747
|
return buildOrmQueryPlan(contract, ast, params);
|
|
@@ -1706,8 +1815,9 @@ function jsonEntryProjection(value, identity) {
|
|
|
1706
1815
|
if (identity.document === true) return new JsonDocumentProjection(value);
|
|
1707
1816
|
return new NativeJsonValueProjection(value);
|
|
1708
1817
|
}
|
|
1709
|
-
function buildProjection(contract,
|
|
1710
|
-
|
|
1818
|
+
function buildProjection(contract, modelName, table, selectedFields, projectedThrough) {
|
|
1819
|
+
const { namespaceId, tableName } = table.storage;
|
|
1820
|
+
return (selectedFields !== void 0 ? [...selectedFields] : getColumnsReadOnTable(contract, namespaceId, modelName, tableName)).map((column) => ProjectionItem.of(column, projectedThrough === void 0 ? table.column(column) : ColumnRef.of(projectedThrough, column), codecRefForStorageColumn(contract.storage, namespaceId, tableName, column)));
|
|
1711
1821
|
}
|
|
1712
1822
|
function appendUnique(values, value) {
|
|
1713
1823
|
if (!values.includes(value)) values.push(value);
|
|
@@ -1715,7 +1825,7 @@ function appendUnique(values, value) {
|
|
|
1715
1825
|
function resolvePolymorphicProjectionSelection(contract, namespaceId, modelName, polyInfo, state) {
|
|
1716
1826
|
if (state.selectedFields === void 0) return {
|
|
1717
1827
|
baseSelectedFields: void 0,
|
|
1718
|
-
|
|
1828
|
+
selectedMtiColumnsByVariant: void 0,
|
|
1719
1829
|
needsHiddenDiscriminator: false
|
|
1720
1830
|
};
|
|
1721
1831
|
const baseColumnToField = getModelColumnFields(contract, namespaceId, modelName);
|
|
@@ -1724,7 +1834,7 @@ function resolvePolymorphicProjectionSelection(contract, namespaceId, modelName,
|
|
|
1724
1834
|
columnToField: getOwnColumnFields(contract, namespaceId, variant.modelName)
|
|
1725
1835
|
}));
|
|
1726
1836
|
const baseSelectedFields = [];
|
|
1727
|
-
const
|
|
1837
|
+
const selectedMtiColumnsByVariant = /* @__PURE__ */ new Map();
|
|
1728
1838
|
let hasVariantOwnedSelection = false;
|
|
1729
1839
|
for (const column of state.selectedFields) {
|
|
1730
1840
|
const isBaseColumn = Object.hasOwn(baseColumnToField, column);
|
|
@@ -1738,10 +1848,10 @@ function resolvePolymorphicProjectionSelection(contract, namespaceId, modelName,
|
|
|
1738
1848
|
appendUnique(baseSelectedFields, column);
|
|
1739
1849
|
continue;
|
|
1740
1850
|
}
|
|
1741
|
-
let selectedColumns =
|
|
1851
|
+
let selectedColumns = selectedMtiColumnsByVariant.get(variant.modelName);
|
|
1742
1852
|
if (selectedColumns === void 0) {
|
|
1743
1853
|
selectedColumns = /* @__PURE__ */ new Set();
|
|
1744
|
-
|
|
1854
|
+
selectedMtiColumnsByVariant.set(variant.modelName, selectedColumns);
|
|
1745
1855
|
}
|
|
1746
1856
|
selectedColumns.add(column);
|
|
1747
1857
|
}
|
|
@@ -1749,13 +1859,13 @@ function resolvePolymorphicProjectionSelection(contract, namespaceId, modelName,
|
|
|
1749
1859
|
}
|
|
1750
1860
|
return {
|
|
1751
1861
|
baseSelectedFields,
|
|
1752
|
-
|
|
1862
|
+
selectedMtiColumnsByVariant,
|
|
1753
1863
|
needsHiddenDiscriminator: state.variantName === void 0 && hasVariantOwnedSelection && !baseSelectedFields.includes(polyInfo.discriminatorColumn)
|
|
1754
1864
|
};
|
|
1755
1865
|
}
|
|
1756
|
-
function buildHiddenDiscriminatorProjection(contract,
|
|
1866
|
+
function buildHiddenDiscriminatorProjection(contract, table, polyInfo, needed) {
|
|
1757
1867
|
if (!needed) return [];
|
|
1758
|
-
return [ProjectionItem.of(POLYMORPHIC_DISCRIMINATOR_ALIAS,
|
|
1868
|
+
return [ProjectionItem.of(POLYMORPHIC_DISCRIMINATOR_ALIAS, table.column(polyInfo.discriminatorColumn), codecRefForStorageColumn(contract.storage, table.storage.namespaceId, table.storage.tableName, polyInfo.discriminatorColumn))];
|
|
1759
1869
|
}
|
|
1760
1870
|
function buildIncludeOrderArtifacts(relationName, rowAlias, childOrderBy) {
|
|
1761
1871
|
if (!childOrderBy || childOrderBy.length === 0) return {
|
|
@@ -1777,41 +1887,34 @@ function buildIncludeOrderArtifacts(relationName, rowAlias, childOrderBy) {
|
|
|
1777
1887
|
function localColumnsForRowInclude(include) {
|
|
1778
1888
|
return include.through?.parentLocalColumns ?? include.localColumns;
|
|
1779
1889
|
}
|
|
1780
|
-
function buildIncludeJoinExpr(include,
|
|
1890
|
+
function buildIncludeJoinExpr(include, child, parentLocalRefs) {
|
|
1781
1891
|
invariant(parentLocalRefs.length === include.targetColumns.length, `Include '${include.relationName}' has mismatched join column counts: ${parentLocalRefs.length} local, ${include.targetColumns.length} target`);
|
|
1782
1892
|
const joinExprs = include.targetColumns.map((targetColumn, i) => {
|
|
1783
1893
|
const parentLocalRef = parentLocalRefs[i];
|
|
1784
1894
|
assertDefined(parentLocalRef, `Include '${include.relationName}': no local column at ${i}`);
|
|
1785
|
-
return BinaryExpr.eq(
|
|
1895
|
+
return BinaryExpr.eq(child.column(targetColumn), parentLocalRef);
|
|
1786
1896
|
});
|
|
1787
1897
|
const [firstExpr] = joinExprs;
|
|
1788
1898
|
assertDefined(firstExpr, `Include '${include.relationName}' has no join columns`);
|
|
1789
1899
|
return joinExprs.length === 1 ? firstExpr : AndExpr.of(joinExprs);
|
|
1790
1900
|
}
|
|
1791
|
-
function
|
|
1901
|
+
function localTable(tables, include) {
|
|
1902
|
+
return include.localVariantName === void 0 ? tables.root : requireVariantTable(tables, include.localVariantName);
|
|
1903
|
+
}
|
|
1904
|
+
function resolveParentLocalRefs(parent, include, localColumns) {
|
|
1905
|
+
const local = localTable(parent.tables, include);
|
|
1906
|
+
const { projectedThrough } = parent;
|
|
1792
1907
|
return localColumns.map((column) => {
|
|
1793
|
-
if (
|
|
1794
|
-
|
|
1795
|
-
return ColumnRef.of(include.localTableName, column);
|
|
1908
|
+
if (projectedThrough === void 0) return local.column(column);
|
|
1909
|
+
return ColumnRef.of(projectedThrough, local === parent.tables.root ? column : variantColumnLabel(local, column));
|
|
1796
1910
|
});
|
|
1797
1911
|
}
|
|
1798
|
-
function
|
|
1799
|
-
|
|
1800
|
-
return
|
|
1801
|
-
alias,
|
|
1802
|
-
tableRef: alias ?? include.relatedTableName
|
|
1803
|
-
};
|
|
1912
|
+
function requireJunction(include) {
|
|
1913
|
+
if (include.junction === void 0) throw new InternalError(`Include '${include.relationName}' goes through a junction table but carries no aliased table for it`);
|
|
1914
|
+
return include.junction;
|
|
1804
1915
|
}
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
* includes attached to a child SELECT. Used by `buildIncludeChildRowsSelect`
|
|
1808
|
-
* to wire depth-2+ aggregates into the inner SELECT at each level.
|
|
1809
|
-
*
|
|
1810
|
-
* Each nested include contributes a single projection item whose
|
|
1811
|
-
* expression is a correlated subquery.
|
|
1812
|
-
*/
|
|
1813
|
-
function buildNestedIncludeProjections(contract, aggregates, parentSource, includes) {
|
|
1814
|
-
return includes.map((nested) => buildCorrelatedIncludeProjection(contract, aggregates, parentSource, nested).projection);
|
|
1916
|
+
function buildNestedIncludeProjections(contract, aggregates, scope, parent, includes) {
|
|
1917
|
+
return includes.map((nested) => buildCorrelatedIncludeProjection(contract, aggregates, scope, parent, nested).projection);
|
|
1815
1918
|
}
|
|
1816
1919
|
/**
|
|
1817
1920
|
* The aliases a level's nested includes contribute. Each such subquery
|
|
@@ -1829,13 +1932,8 @@ function documentAliasesOf(nestedProjections) {
|
|
|
1829
1932
|
* variant-specific columns live on the base table and reach the row through
|
|
1830
1933
|
* the ordinary base-column projection (`buildProjection`); only the MTI
|
|
1831
1934
|
* variant tables need a join.
|
|
1832
|
-
*
|
|
1833
|
-
* When the child base table is aliased (self-relations), `buildMtiJoins`
|
|
1834
|
-
* emits a join `ON` against the unaliased base table name, which would fall
|
|
1835
|
-
* out of scope. Remap it to the child alias — the same remap the row builder
|
|
1836
|
-
* already applies to `orderBy`/`where`.
|
|
1837
1935
|
*/
|
|
1838
|
-
function buildChildPolymorphismJoinsAndProjection(contract, include
|
|
1936
|
+
function buildChildPolymorphismJoinsAndProjection(contract, include) {
|
|
1839
1937
|
const polyInfo = resolvePolymorphismInfo(contract, include.relatedNamespaceId, include.relatedModelName);
|
|
1840
1938
|
if (!polyInfo) return {
|
|
1841
1939
|
joins: [],
|
|
@@ -1844,35 +1942,25 @@ function buildChildPolymorphismJoinsAndProjection(contract, include, childTableA
|
|
|
1844
1942
|
baseSelectedFields: include.nested.selectedFields
|
|
1845
1943
|
};
|
|
1846
1944
|
const selection = resolvePolymorphicProjectionSelection(contract, include.relatedNamespaceId, include.relatedModelName, polyInfo, include.nested);
|
|
1847
|
-
const { joins, projection } = buildMtiJoins(contract, include.
|
|
1848
|
-
const hiddenProjection = buildHiddenDiscriminatorProjection(contract, include.relatedNamespaceId, polyInfo, childTableRef, selection.needsHiddenDiscriminator);
|
|
1849
|
-
if (!childTableAlias) return {
|
|
1850
|
-
joins,
|
|
1851
|
-
projection,
|
|
1852
|
-
hiddenProjection,
|
|
1853
|
-
baseSelectedFields: selection.baseSelectedFields
|
|
1854
|
-
};
|
|
1855
|
-
const remapper = createTableRefRemapper$1(polyInfo.baseTable, childTableRef);
|
|
1945
|
+
const { joins, projection } = buildMtiJoins(contract, include.nested.tables, polyInfo, include.nested.variantName, selection.selectedMtiColumnsByVariant);
|
|
1856
1946
|
return {
|
|
1857
|
-
joins
|
|
1947
|
+
joins,
|
|
1858
1948
|
projection,
|
|
1859
|
-
hiddenProjection,
|
|
1949
|
+
hiddenProjection: buildHiddenDiscriminatorProjection(contract, include.nested.tables.root, polyInfo, selection.needsHiddenDiscriminator),
|
|
1860
1950
|
baseSelectedFields: selection.baseSelectedFields
|
|
1861
1951
|
};
|
|
1862
1952
|
}
|
|
1863
1953
|
function buildRequiredMtiJoinKeyProjection(contract, include) {
|
|
1864
|
-
const polyInfo = resolvePolymorphismInfo(contract, include.relatedNamespaceId, include.relatedModelName);
|
|
1865
|
-
if (!polyInfo) return [];
|
|
1866
|
-
const mtiTables = new Set(polyInfo.mtiVariants.map((variant) => variant.table));
|
|
1867
1954
|
const aliases = /* @__PURE__ */ new Set();
|
|
1868
1955
|
const projection = [];
|
|
1869
1956
|
for (const nested of include.nested.includes) {
|
|
1870
|
-
if (
|
|
1957
|
+
if (nested.localVariantName === void 0) continue;
|
|
1958
|
+
const variantTable = requireVariantTable(include.nested.tables, nested.localVariantName);
|
|
1871
1959
|
for (const column of localColumnsForRowInclude(nested)) {
|
|
1872
|
-
const alias =
|
|
1960
|
+
const alias = variantColumnLabel(variantTable, column);
|
|
1873
1961
|
if (aliases.has(alias)) continue;
|
|
1874
1962
|
aliases.add(alias);
|
|
1875
|
-
projection.push(ProjectionItem.of(alias,
|
|
1963
|
+
projection.push(ProjectionItem.of(alias, variantTable.column(column), codecRefForStorageColumn(contract.storage, variantTable.storage.namespaceId, variantTable.storage.tableName, column)));
|
|
1876
1964
|
}
|
|
1877
1965
|
}
|
|
1878
1966
|
return projection;
|
|
@@ -1892,61 +1980,54 @@ function mergeProjectionByAlias(projection, additional) {
|
|
|
1892
1980
|
* (AND-ed across all column pairs for composite keys). The junction JOIN
|
|
1893
1981
|
* connects child rows to the junction via the child columns.
|
|
1894
1982
|
*/
|
|
1895
|
-
function buildManyToManyJunctionArtifacts(parentLocalRefs,
|
|
1896
|
-
const { table: junctionTable, parentColumns, childColumns, targetColumns
|
|
1983
|
+
function buildManyToManyJunctionArtifacts(contract, parentLocalRefs, child, junction, through) {
|
|
1984
|
+
const { table: junctionTable, parentColumns, childColumns, targetColumns } = through;
|
|
1897
1985
|
invariant(childColumns.length === targetColumns.length, `M:N junction '${junctionTable}': childColumns (${childColumns.length}) and targetColumns (${targetColumns.length}) must have equal length`);
|
|
1898
1986
|
invariant(parentColumns.length === parentLocalRefs.length, `M:N junction '${junctionTable}': parentColumns (${parentColumns.length}) and parentLocalColumns (${parentLocalRefs.length}) must have equal length`);
|
|
1899
1987
|
const joinOnPairs = childColumns.map((junctionCol, i) => {
|
|
1900
1988
|
const targetCol = targetColumns[i];
|
|
1901
1989
|
assertDefined(targetCol, `M:N junction '${junctionTable}': missing target column at index ${i}`);
|
|
1902
|
-
return BinaryExpr.eq(
|
|
1990
|
+
return BinaryExpr.eq(junction.column(junctionCol), child.column(targetCol));
|
|
1903
1991
|
});
|
|
1904
1992
|
const firstJoinPair = joinOnPairs[0];
|
|
1905
1993
|
const joinOn = joinOnPairs.length === 1 && firstJoinPair ? firstJoinPair : AndExpr.of(joinOnPairs);
|
|
1906
1994
|
const correlationPairs = parentColumns.map((junctionCol, i) => {
|
|
1907
1995
|
const parentLocalRef = parentLocalRefs[i];
|
|
1908
1996
|
assertDefined(parentLocalRef, `M:N junction '${junctionTable}': missing parent-local column ref at index ${i}`);
|
|
1909
|
-
return BinaryExpr.eq(
|
|
1997
|
+
return BinaryExpr.eq(junction.column(junctionCol), parentLocalRef);
|
|
1910
1998
|
});
|
|
1911
1999
|
const firstCorrelationPair = correlationPairs[0];
|
|
1912
2000
|
return {
|
|
1913
2001
|
whereExpr: correlationPairs.length === 1 && firstCorrelationPair ? firstCorrelationPair : AndExpr.of(correlationPairs),
|
|
1914
|
-
junctionJoin: JoinAst.inner(
|
|
2002
|
+
junctionJoin: JoinAst.inner(junction.tableSource(contract), joinOn, false)
|
|
1915
2003
|
};
|
|
1916
2004
|
}
|
|
1917
|
-
function buildIncludeChildRowsSelect(contract, aggregates,
|
|
2005
|
+
function buildIncludeChildRowsSelect(contract, aggregates, scope, parent, include) {
|
|
1918
2006
|
const childState = include.nested;
|
|
1919
2007
|
if (childState.distinctOn !== void 0 && childState.distinctOn.length > 0) {
|
|
1920
2008
|
assertDistinctOnCapability(contract, "distinctOn");
|
|
1921
2009
|
assertDistinctOnCompatibleOrder(childState.orderBy, childState.distinctOn.length);
|
|
1922
2010
|
}
|
|
1923
|
-
const
|
|
1924
|
-
const
|
|
1925
|
-
const
|
|
1926
|
-
const
|
|
1927
|
-
const
|
|
1928
|
-
const remappedChildOrderBy = childTableAlias && childState.orderBy ? childState.orderBy.map((item) => item.rewrite(createTableRefRemapper$1(include.relatedTableName, childTableRef))) : childState.orderBy;
|
|
1929
|
-
const { childOrderBy, hiddenOrderProjection, aggregateOrderBy } = buildIncludeOrderArtifacts(include.relationName, rowsAlias, remappedChildOrderBy);
|
|
1930
|
-
const childWhere = buildStateWhere(contract, childTableRef, childState, {
|
|
1931
|
-
filterTableName: include.relatedTableName,
|
|
1932
|
-
namespaceId: include.relatedNamespaceId
|
|
1933
|
-
});
|
|
2011
|
+
const child = childState.tables.root;
|
|
2012
|
+
const parentLocalRefs = resolveParentLocalRefs(parent, include, localColumnsForRowInclude(include));
|
|
2013
|
+
const rowsAlias = scope.alias(`${include.relationName}__rows`);
|
|
2014
|
+
const { childOrderBy, hiddenOrderProjection, aggregateOrderBy } = buildIncludeOrderArtifacts(include.relationName, rowsAlias, childState.orderBy);
|
|
2015
|
+
const childWhere = buildStateWhere(contract, childState);
|
|
1934
2016
|
let whereExpr;
|
|
1935
2017
|
let junctionJoins = [];
|
|
1936
2018
|
if (include.through !== void 0) {
|
|
1937
|
-
const artifacts = buildManyToManyJunctionArtifacts(parentLocalRefs,
|
|
2019
|
+
const artifacts = buildManyToManyJunctionArtifacts(contract, parentLocalRefs, child, requireJunction(include), include.through);
|
|
1938
2020
|
whereExpr = childWhere ? AndExpr.of([artifacts.whereExpr, childWhere]) : artifacts.whereExpr;
|
|
1939
2021
|
junctionJoins = [artifacts.junctionJoin];
|
|
1940
2022
|
} else {
|
|
1941
|
-
const joinExpr = buildIncludeJoinExpr(include,
|
|
2023
|
+
const joinExpr = buildIncludeJoinExpr(include, child, parentLocalRefs);
|
|
1942
2024
|
whereExpr = childWhere ? AndExpr.of([joinExpr, childWhere]) : joinExpr;
|
|
1943
2025
|
}
|
|
1944
2026
|
if (childState.distinct !== void 0 && childState.distinct.length > 0 && childState.includes.length > 0) return buildDistinctNonLeafChildRowsSelect({
|
|
1945
2027
|
contract,
|
|
1946
2028
|
aggregates,
|
|
2029
|
+
scope,
|
|
1947
2030
|
include,
|
|
1948
|
-
childTableAlias,
|
|
1949
|
-
childTableRef,
|
|
1950
2031
|
rowsAlias,
|
|
1951
2032
|
childOrderBy,
|
|
1952
2033
|
hiddenOrderProjection,
|
|
@@ -1954,30 +2035,26 @@ function buildIncludeChildRowsSelect(contract, aggregates, parentSource, include
|
|
|
1954
2035
|
whereExpr,
|
|
1955
2036
|
junctionJoins
|
|
1956
2037
|
});
|
|
1957
|
-
const polyJoinsAndProjection = buildChildPolymorphismJoinsAndProjection(contract, include
|
|
1958
|
-
const scalarProjection = buildProjection(contract,
|
|
1959
|
-
const nestedProjections = buildNestedIncludeProjections(contract, aggregates, {
|
|
1960
|
-
baseTableName: include.relatedTableName,
|
|
1961
|
-
tableRef: childTableRef,
|
|
1962
|
-
variantColumnsProjected: false
|
|
1963
|
-
}, childState.includes);
|
|
2038
|
+
const polyJoinsAndProjection = buildChildPolymorphismJoinsAndProjection(contract, include);
|
|
2039
|
+
const scalarProjection = buildProjection(contract, addressedModelName(include.relatedModelName, include.nested.variantName), child, polyJoinsAndProjection.baseSelectedFields);
|
|
2040
|
+
const nestedProjections = buildNestedIncludeProjections(contract, aggregates, scope, { tables: childState.tables }, childState.includes);
|
|
1964
2041
|
const childProjection = [
|
|
1965
2042
|
...scalarProjection,
|
|
1966
2043
|
...polyJoinsAndProjection.projection,
|
|
1967
2044
|
...polyJoinsAndProjection.hiddenProjection,
|
|
1968
2045
|
...nestedProjections
|
|
1969
2046
|
];
|
|
1970
|
-
let childRows = SelectAst.from(
|
|
2047
|
+
let childRows = SelectAst.from(child.tableSource(contract)).withProjection([...childProjection, ...hiddenOrderProjection]).withWhere(whereExpr);
|
|
1971
2048
|
if (polyJoinsAndProjection.joins.length > 0) childRows = childRows.withJoins([...polyJoinsAndProjection.joins]);
|
|
1972
2049
|
if (junctionJoins.length > 0) childRows = childRows.withJoins(junctionJoins);
|
|
1973
2050
|
if (childState.distinctOn && childState.distinctOn.length > 0) {
|
|
1974
|
-
childRows = childRows.withDistinctOn(childState.distinctOn.map((column) =>
|
|
2051
|
+
childRows = childRows.withDistinctOn(childState.distinctOn.map((column) => child.column(column)));
|
|
1975
2052
|
if (childOrderBy) childRows = childRows.withOrderBy(childOrderBy);
|
|
1976
2053
|
} else if (childState.distinct && childState.distinct.length > 0) {
|
|
1977
|
-
const rankedAlias = `${include.relationName}__distinct
|
|
2054
|
+
const rankedAlias = scope.alias(`${include.relationName}__distinct`);
|
|
1978
2055
|
childRows = wrapWithRowNumberDedup({
|
|
1979
2056
|
base: childRows,
|
|
1980
|
-
distinctColumnRefs: childState.distinct.map((column) =>
|
|
2057
|
+
distinctColumnRefs: childState.distinct.map((column) => child.column(column)),
|
|
1981
2058
|
rankingOrderBy: childOrderBy ?? [],
|
|
1982
2059
|
rankedAlias
|
|
1983
2060
|
});
|
|
@@ -1994,21 +2071,22 @@ function buildIncludeChildRowsSelect(contract, aggregates, parentSource, include
|
|
|
1994
2071
|
};
|
|
1995
2072
|
}
|
|
1996
2073
|
function buildDistinctNonLeafChildRowsSelect(options) {
|
|
1997
|
-
const { contract, aggregates,
|
|
2074
|
+
const { contract, aggregates, scope, include, rowsAlias, childOrderBy, hiddenOrderProjection, aggregateOrderBy, whereExpr, junctionJoins } = options;
|
|
1998
2075
|
const childState = include.nested;
|
|
1999
|
-
const
|
|
2076
|
+
const child = childState.tables.root;
|
|
2077
|
+
const grandchildJoinColumns = Array.from(new Set(childState.includes.flatMap((nested) => nested.localVariantName === void 0 ? localColumnsForRowInclude(nested) : [])));
|
|
2000
2078
|
const { selectedForQuery } = augmentSelectionForJoinColumns(childState.selectedFields, grandchildJoinColumns);
|
|
2001
|
-
const visiblePolyProjection = buildChildPolymorphismJoinsAndProjection(contract, include
|
|
2079
|
+
const visiblePolyProjection = buildChildPolymorphismJoinsAndProjection(contract, include);
|
|
2002
2080
|
const queryPolyProjection = buildChildPolymorphismJoinsAndProjection(contract, {
|
|
2003
2081
|
...include,
|
|
2004
2082
|
nested: {
|
|
2005
2083
|
...childState,
|
|
2006
2084
|
selectedFields: selectedForQuery
|
|
2007
2085
|
}
|
|
2008
|
-
}
|
|
2009
|
-
const innerScalarProjection = buildProjection(contract,
|
|
2086
|
+
});
|
|
2087
|
+
const innerScalarProjection = buildProjection(contract, addressedModelName(include.relatedModelName, include.nested.variantName), child, queryPolyProjection.baseSelectedFields);
|
|
2010
2088
|
const innerMtiProjection = mergeProjectionByAlias(queryPolyProjection.projection, buildRequiredMtiJoinKeyProjection(contract, include));
|
|
2011
|
-
let baseInner = SelectAst.from(
|
|
2089
|
+
let baseInner = SelectAst.from(child.tableSource(contract)).withProjection([
|
|
2012
2090
|
...innerScalarProjection,
|
|
2013
2091
|
...innerMtiProjection,
|
|
2014
2092
|
...queryPolyProjection.hiddenProjection,
|
|
@@ -2018,22 +2096,21 @@ function buildDistinctNonLeafChildRowsSelect(options) {
|
|
|
2018
2096
|
if (distinctExtraJoins.length > 0) baseInner = baseInner.withJoins(distinctExtraJoins);
|
|
2019
2097
|
const distinctColumns = childState.distinct;
|
|
2020
2098
|
if (distinctColumns === void 0 || distinctColumns.length === 0) throw new InternalError("buildDistinctNonLeafChildRowsSelect requires a non-empty `distinct` selection");
|
|
2021
|
-
const rankedAlias = `${include.relationName}__ranked
|
|
2099
|
+
const rankedAlias = scope.alias(`${include.relationName}__ranked`);
|
|
2022
2100
|
let innerSelect = wrapWithRowNumberDedup({
|
|
2023
2101
|
base: baseInner,
|
|
2024
|
-
distinctColumnRefs: distinctColumns.map((column) =>
|
|
2102
|
+
distinctColumnRefs: distinctColumns.map((column) => child.column(column)),
|
|
2025
2103
|
rankingOrderBy: childOrderBy ?? [],
|
|
2026
2104
|
rankedAlias
|
|
2027
2105
|
});
|
|
2028
2106
|
if (childOrderBy) innerSelect = innerSelect.withOrderBy(childOrderBy.map((item, index) => item.withExpr(ColumnRef.of(rankedAlias, `${include.relationName}__order_${index}`))));
|
|
2029
2107
|
if (childState.limit !== void 0) innerSelect = innerSelect.withLimit(childState.limit);
|
|
2030
2108
|
if (childState.offset !== void 0) innerSelect = innerSelect.withOffset(childState.offset);
|
|
2031
|
-
const distinctAlias = `${include.relationName}__distinct
|
|
2032
|
-
const outerScalarProjection = buildProjection(contract,
|
|
2033
|
-
const outerNestedProjections = buildNestedIncludeProjections(contract, aggregates, {
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
variantColumnsProjected: true
|
|
2109
|
+
const distinctAlias = scope.alias(`${include.relationName}__distinct`);
|
|
2110
|
+
const outerScalarProjection = buildProjection(contract, addressedModelName(include.relatedModelName, include.nested.variantName), child, visiblePolyProjection.baseSelectedFields, distinctAlias);
|
|
2111
|
+
const outerNestedProjections = buildNestedIncludeProjections(contract, aggregates, scope, {
|
|
2112
|
+
tables: childState.tables,
|
|
2113
|
+
projectedThrough: distinctAlias
|
|
2037
2114
|
}, childState.includes);
|
|
2038
2115
|
const outerPolyProjection = visiblePolyProjection.projection.map((proj) => ProjectionItem.of(proj.alias, ColumnRef.of(distinctAlias, proj.alias), proj.codec));
|
|
2039
2116
|
const outerHiddenProjection = visiblePolyProjection.hiddenProjection.map((proj) => ProjectionItem.of(proj.alias, ColumnRef.of(distinctAlias, proj.alias), proj.codec));
|
|
@@ -2078,7 +2155,7 @@ function buildDistinctNonLeafChildRowsSelect(options) {
|
|
|
2078
2155
|
* `distinct`) is dropped at the SQL level since reordering does not
|
|
2079
2156
|
* change which rows are aggregated.
|
|
2080
2157
|
*/
|
|
2081
|
-
function buildIncludeChildScalarSelect(contract, aggregates,
|
|
2158
|
+
function buildIncludeChildScalarSelect(contract, aggregates, scope, parent, include, scalar) {
|
|
2082
2159
|
const { codec: resultCodec, input: inputCodec, lower: resultLowering } = resolveAggregate({
|
|
2083
2160
|
aggregates,
|
|
2084
2161
|
contract,
|
|
@@ -2087,65 +2164,58 @@ function buildIncludeChildScalarSelect(contract, aggregates, parentSource, inclu
|
|
|
2087
2164
|
fn: scalar.fn,
|
|
2088
2165
|
column: scalar.column
|
|
2089
2166
|
});
|
|
2090
|
-
const parentLocalRefs = resolveParentLocalRefs(
|
|
2091
|
-
const childSource = resolveChildTableSource(include, parentLocalRefs);
|
|
2092
|
-
const childTableAlias = childSource.alias;
|
|
2093
|
-
const childTableRef = childSource.tableRef;
|
|
2167
|
+
const parentLocalRefs = resolveParentLocalRefs(parent, include, localColumnsForRowInclude(include));
|
|
2094
2168
|
const state = scalar.state;
|
|
2169
|
+
const child = state.tables.root;
|
|
2095
2170
|
if (state.distinctOn !== void 0 && state.distinctOn.length > 0) {
|
|
2096
2171
|
assertDistinctOnCapability(contract, "distinctOn");
|
|
2097
2172
|
assertDistinctOnCompatibleOrder(state.orderBy, state.distinctOn.length);
|
|
2098
2173
|
}
|
|
2099
|
-
const childWhere = buildStateWhere(contract,
|
|
2100
|
-
filterTableName: include.relatedTableName,
|
|
2101
|
-
namespaceId: include.relatedNamespaceId
|
|
2102
|
-
});
|
|
2174
|
+
const childWhere = buildStateWhere(contract, state);
|
|
2103
2175
|
let whereExpr;
|
|
2104
2176
|
let junctionJoins = [];
|
|
2105
2177
|
if (include.through !== void 0) {
|
|
2106
|
-
const artifacts = buildManyToManyJunctionArtifacts(parentLocalRefs,
|
|
2178
|
+
const artifacts = buildManyToManyJunctionArtifacts(contract, parentLocalRefs, child, requireJunction(include), include.through);
|
|
2107
2179
|
whereExpr = childWhere ? AndExpr.of([artifacts.whereExpr, childWhere]) : artifacts.whereExpr;
|
|
2108
2180
|
junctionJoins = [artifacts.junctionJoin];
|
|
2109
2181
|
} else {
|
|
2110
|
-
const joinExpr = buildIncludeJoinExpr(include,
|
|
2182
|
+
const joinExpr = buildIncludeJoinExpr(include, child, parentLocalRefs);
|
|
2111
2183
|
whereExpr = childWhere ? AndExpr.of([joinExpr, childWhere]) : joinExpr;
|
|
2112
2184
|
}
|
|
2113
|
-
const remappedOrderBy = childTableAlias && state.orderBy ? state.orderBy.map((item) => item.rewrite(createTableRefRemapper$1(include.relatedTableName, childTableRef))) : state.orderBy;
|
|
2114
2185
|
const hasPagination = state.limit !== void 0 || state.offset !== void 0;
|
|
2115
2186
|
const hasDistinct = state.distinct !== void 0 && state.distinct.length > 0 || state.distinctOn !== void 0 && state.distinctOn.length > 0;
|
|
2116
2187
|
if (!(hasPagination || hasDistinct)) {
|
|
2117
|
-
const aggregateExpr = buildIncludeAggregateExpr(scalar,
|
|
2188
|
+
const aggregateExpr = buildIncludeAggregateExpr(scalar, scalar.column === void 0 ? void 0 : child.column(scalar.column), resultLowering, inputCodec);
|
|
2118
2189
|
const jsonObjectExpr = JsonObjectExpr.fromEntries([JsonObjectExpr.entry("value", jsonEntryProjection(aggregateExpr, { codec: resultCodec }))]);
|
|
2119
|
-
let select = SelectAst.from(
|
|
2190
|
+
let select = SelectAst.from(child.tableSource(contract)).withProjection([ProjectionItem.of(include.relationName, jsonObjectExpr)]).withWhere(whereExpr);
|
|
2120
2191
|
if (junctionJoins.length > 0) select = select.withJoins(junctionJoins);
|
|
2121
2192
|
return select;
|
|
2122
2193
|
}
|
|
2123
|
-
const innerAlias = `${include.relationName}__scalar
|
|
2124
|
-
const hiddenOrderProjection = state.distinct !== void 0 && state.distinct.length > 0 &&
|
|
2125
|
-
const innerProjection = [...scalar.column !== void 0 ? [ProjectionItem.of(scalar.column,
|
|
2126
|
-
let inner = SelectAst.from(
|
|
2194
|
+
const innerAlias = scope.alias(`${include.relationName}__scalar`);
|
|
2195
|
+
const hiddenOrderProjection = state.distinct !== void 0 && state.distinct.length > 0 && state.orderBy !== void 0 && state.orderBy.length > 0 ? state.orderBy.map((item, index) => ProjectionItem.of(`${include.relationName}__order_${index}`, item.expr)) : [];
|
|
2196
|
+
const innerProjection = [...scalar.column !== void 0 ? [ProjectionItem.of(scalar.column, child.column(scalar.column))] : [ProjectionItem.of("__row", LiteralExpr.of(1))], ...hiddenOrderProjection];
|
|
2197
|
+
let inner = SelectAst.from(child.tableSource(contract)).withProjection(innerProjection).withWhere(whereExpr);
|
|
2127
2198
|
if (junctionJoins.length > 0) inner = inner.withJoins(junctionJoins);
|
|
2128
2199
|
if (state.distinctOn !== void 0 && state.distinctOn.length > 0) {
|
|
2129
|
-
inner = inner.withDistinctOn(state.distinctOn.map((column) =>
|
|
2130
|
-
if (
|
|
2200
|
+
inner = inner.withDistinctOn(state.distinctOn.map((column) => child.column(column)));
|
|
2201
|
+
if (state.orderBy !== void 0 && state.orderBy.length > 0) inner = inner.withOrderBy(state.orderBy);
|
|
2131
2202
|
} else if (state.distinct !== void 0 && state.distinct.length > 0) {
|
|
2132
|
-
const rankedAlias = `${include.relationName}__scalar_distinct
|
|
2203
|
+
const rankedAlias = scope.alias(`${include.relationName}__scalar_distinct`);
|
|
2133
2204
|
inner = wrapWithRowNumberDedup({
|
|
2134
2205
|
base: inner,
|
|
2135
|
-
distinctColumnRefs: state.distinct.map((column) =>
|
|
2136
|
-
rankingOrderBy:
|
|
2206
|
+
distinctColumnRefs: state.distinct.map((column) => child.column(column)),
|
|
2207
|
+
rankingOrderBy: state.orderBy ?? [],
|
|
2137
2208
|
rankedAlias
|
|
2138
2209
|
});
|
|
2139
|
-
if (
|
|
2140
|
-
} else if (
|
|
2210
|
+
if (state.orderBy !== void 0 && state.orderBy.length > 0) inner = inner.withOrderBy(state.orderBy.map((item, index) => item.withExpr(ColumnRef.of(rankedAlias, `${include.relationName}__order_${index}`))));
|
|
2211
|
+
} else if (state.orderBy !== void 0 && state.orderBy.length > 0) inner = inner.withOrderBy(state.orderBy);
|
|
2141
2212
|
if (state.limit !== void 0) inner = inner.withLimit(state.limit);
|
|
2142
2213
|
if (state.offset !== void 0) inner = inner.withOffset(state.offset);
|
|
2143
|
-
const outerAggregateExpr = buildIncludeAggregateExpr(scalar, innerAlias, resultLowering, inputCodec);
|
|
2214
|
+
const outerAggregateExpr = buildIncludeAggregateExpr(scalar, scalar.column === void 0 ? void 0 : ColumnRef.of(innerAlias, scalar.column), resultLowering, inputCodec);
|
|
2144
2215
|
const outerJsonObjectExpr = JsonObjectExpr.fromEntries([JsonObjectExpr.entry("value", jsonEntryProjection(outerAggregateExpr, { codec: resultCodec }))]);
|
|
2145
2216
|
return SelectAst.from(DerivedTableSource.as(innerAlias, inner)).withProjection([ProjectionItem.of(include.relationName, outerJsonObjectExpr)]);
|
|
2146
2217
|
}
|
|
2147
|
-
function buildIncludeAggregateExpr(scalar,
|
|
2148
|
-
const expr = scalar.column === void 0 ? void 0 : ColumnRef.of(childTableRef, scalar.column);
|
|
2218
|
+
function buildIncludeAggregateExpr(scalar, expr, lower, inputCodec) {
|
|
2149
2219
|
if (lower !== void 0) return lower({
|
|
2150
2220
|
expr,
|
|
2151
2221
|
inputCodec
|
|
@@ -2171,13 +2241,13 @@ function buildIncludeAggregateExpr(scalar, childTableRef, lower, inputCodec) {
|
|
|
2171
2241
|
* branch fan out naturally because the row builder is invoked with
|
|
2172
2242
|
* a synthetic IncludeExpr whose `nested` is the branch's state.
|
|
2173
2243
|
*/
|
|
2174
|
-
function buildIncludeChildCombineSelect(contract, aggregates,
|
|
2244
|
+
function buildIncludeChildCombineSelect(contract, aggregates, scope, parent, include, branches) {
|
|
2175
2245
|
const branchEntries = Object.entries(branches);
|
|
2176
2246
|
if (branchEntries.length === 0) throw ormError("ORM.INCLUDE_INVALID", `combine() include "${include.relationName}" has no branches`, { meta: { relation: include.relationName } });
|
|
2177
2247
|
const compiledBranches = branchEntries.map(([name, branch]) => ({
|
|
2178
2248
|
name,
|
|
2179
|
-
alias: `${include.relationName}__combine__${name}
|
|
2180
|
-
select: buildIncludeChildCombineBranchSelect(contract, aggregates,
|
|
2249
|
+
alias: scope.alias(`${include.relationName}__combine__${name}`),
|
|
2250
|
+
select: buildIncludeChildCombineBranchSelect(contract, aggregates, scope, parent, include, branch)
|
|
2181
2251
|
}));
|
|
2182
2252
|
const jsonObjectExpr = JsonObjectExpr.fromEntries(compiledBranches.map((branch) => JsonObjectExpr.entry(branch.name, jsonEntryProjection(ColumnRef.of(branch.alias, include.relationName), { document: true }))));
|
|
2183
2253
|
const [firstBranch, ...restBranches] = compiledBranches;
|
|
@@ -2191,9 +2261,9 @@ function buildIncludeChildCombineSelect(contract, aggregates, parentSource, incl
|
|
|
2191
2261
|
* relation name. Dispatches to the standalone scalar / row builders
|
|
2192
2262
|
* with the branch's state spliced into a synthetic IncludeExpr.
|
|
2193
2263
|
*/
|
|
2194
|
-
function buildIncludeChildCombineBranchSelect(contract, aggregates,
|
|
2195
|
-
if (branch.kind === "scalar") return buildIncludeChildScalarSelect(contract, aggregates,
|
|
2196
|
-
return buildIncludeChildRowsAggregateSelect(contract, aggregates,
|
|
2264
|
+
function buildIncludeChildCombineBranchSelect(contract, aggregates, scope, parent, include, branch) {
|
|
2265
|
+
if (branch.kind === "scalar") return buildIncludeChildScalarSelect(contract, aggregates, scope, parent, include, branch.selector);
|
|
2266
|
+
return buildIncludeChildRowsAggregateSelect(contract, aggregates, scope, parent, {
|
|
2197
2267
|
...include,
|
|
2198
2268
|
nested: branch.state,
|
|
2199
2269
|
scalar: void 0,
|
|
@@ -2206,103 +2276,98 @@ function buildIncludeChildCombineBranchSelect(contract, aggregates, parentSource
|
|
|
2206
2276
|
* name. Used by both the standalone row correlated-subquery path and
|
|
2207
2277
|
* by combine's row branches.
|
|
2208
2278
|
*/
|
|
2209
|
-
function buildIncludeChildRowsAggregateSelect(contract, aggregates,
|
|
2210
|
-
const { childRows, childProjection, documentAliases, rowsAlias, aggregateOrderBy } = buildIncludeChildRowsSelect(contract, aggregates,
|
|
2279
|
+
function buildIncludeChildRowsAggregateSelect(contract, aggregates, scope, parent, include) {
|
|
2280
|
+
const { childRows, childProjection, documentAliases, rowsAlias, aggregateOrderBy } = buildIncludeChildRowsSelect(contract, aggregates, scope, parent, include);
|
|
2211
2281
|
const jsonObjectExpr = JsonObjectExpr.fromEntries(childProjection.map((item) => JsonObjectExpr.entry(item.alias, jsonEntryProjection(ColumnRef.of(rowsAlias, item.alias), {
|
|
2212
2282
|
codec: item.codec,
|
|
2213
2283
|
document: documentAliases.has(item.alias)
|
|
2214
2284
|
}))));
|
|
2215
2285
|
return SelectAst.from(DerivedTableSource.as(rowsAlias, childRows)).withProjection([ProjectionItem.of(include.relationName, JsonArrayAggExpr.of(jsonEntryProjection(jsonObjectExpr, { document: true }), "emptyArray", aggregateOrderBy))]);
|
|
2216
2286
|
}
|
|
2217
|
-
function buildCorrelatedIncludeProjection(contract, aggregates,
|
|
2287
|
+
function buildCorrelatedIncludeProjection(contract, aggregates, scope, parent, include) {
|
|
2218
2288
|
if (include.scalar) {
|
|
2219
|
-
const scalarSelect = buildIncludeChildScalarSelect(contract, aggregates,
|
|
2289
|
+
const scalarSelect = buildIncludeChildScalarSelect(contract, aggregates, scope, parent, include, include.scalar);
|
|
2220
2290
|
return { projection: ProjectionItem.of(include.relationName, SubqueryExpr.of(scalarSelect)) };
|
|
2221
2291
|
}
|
|
2222
2292
|
if (include.combine) {
|
|
2223
|
-
const combineSelect = buildIncludeChildCombineSelect(contract, aggregates,
|
|
2293
|
+
const combineSelect = buildIncludeChildCombineSelect(contract, aggregates, scope, parent, include, include.combine);
|
|
2224
2294
|
return { projection: ProjectionItem.of(include.relationName, SubqueryExpr.of(combineSelect)) };
|
|
2225
2295
|
}
|
|
2226
|
-
const aggregateQuery = buildIncludeChildRowsAggregateSelect(contract, aggregates,
|
|
2296
|
+
const aggregateQuery = buildIncludeChildRowsAggregateSelect(contract, aggregates, scope, parent, include);
|
|
2227
2297
|
return { projection: ProjectionItem.of(include.relationName, SubqueryExpr.of(aggregateQuery)) };
|
|
2228
2298
|
}
|
|
2229
|
-
function buildSelectAst(contract, modelName,
|
|
2230
|
-
const
|
|
2299
|
+
function buildSelectAst(contract, modelName, state, options) {
|
|
2300
|
+
const { root } = state.tables;
|
|
2301
|
+
const { namespaceId, tableName } = root.storage;
|
|
2231
2302
|
if (state.distinctOn !== void 0 && state.distinctOn.length > 0) {
|
|
2232
2303
|
assertDistinctOnCapability(contract, "distinctOn");
|
|
2233
2304
|
assertDistinctOnCompatibleOrder(state.orderBy, state.distinctOn.length);
|
|
2234
2305
|
}
|
|
2235
2306
|
const addressed = addressedModelName(modelName, state.variantName);
|
|
2236
|
-
const projection = [...buildProjection(contract,
|
|
2237
|
-
const { source: fromSource, where: effectiveWhere } = buildDedupedTableSource(contract,
|
|
2307
|
+
const projection = [...buildProjection(contract, addressed, root, state.selectedFields), ...options.includeProjection ?? []];
|
|
2308
|
+
const { source: fromSource, where: effectiveWhere } = buildDedupedTableSource(contract, state, options.where ?? buildStateWhere(contract, state), getColumnsReadOnTable(contract, namespaceId, addressed, tableName).map((column) => ProjectionItem.of(column, root.column(column))));
|
|
2238
2309
|
let ast = SelectAst.from(fromSource).withProjection(projection);
|
|
2239
2310
|
if (effectiveWhere) ast = ast.withWhere(effectiveWhere);
|
|
2240
2311
|
if (state.orderBy) ast = ast.withOrderBy(state.orderBy);
|
|
2241
2312
|
if (state.selectedFields === void 0) ast = ast.withSelectAllIntent({ table: tableName });
|
|
2242
|
-
if (state.distinctOn && state.distinctOn.length > 0) ast = ast.withDistinctOn(state.distinctOn.map((column) =>
|
|
2313
|
+
if (state.distinctOn && state.distinctOn.length > 0) ast = ast.withDistinctOn(state.distinctOn.map((column) => root.column(column)));
|
|
2243
2314
|
if (state.limit !== void 0) ast = ast.withLimit(state.limit);
|
|
2244
2315
|
if (state.offset !== void 0) ast = ast.withOffset(state.offset);
|
|
2245
2316
|
if (options.joins && options.joins.length > 0) ast = ast.withJoins(options.joins);
|
|
2246
2317
|
if (state.locking !== void 0) ast = ast.withLocking(state.locking);
|
|
2247
2318
|
return ast;
|
|
2248
2319
|
}
|
|
2249
|
-
function
|
|
2320
|
+
function buildRootPolymorphism(contract, state, modelName) {
|
|
2321
|
+
const { root } = state.tables;
|
|
2322
|
+
const { namespaceId } = root.storage;
|
|
2323
|
+
const polyInfo = resolvePolymorphismInfo(contract, namespaceId, modelName);
|
|
2324
|
+
if (!polyInfo) return {
|
|
2325
|
+
projectionState: state,
|
|
2326
|
+
joins: [],
|
|
2327
|
+
projection: []
|
|
2328
|
+
};
|
|
2329
|
+
const selection = resolvePolymorphicProjectionSelection(contract, namespaceId, modelName, polyInfo, state);
|
|
2330
|
+
const mtiArtifacts = polyInfo.mtiVariants.length > 0 ? buildMtiJoins(contract, state.tables, polyInfo, state.variantName, selection.selectedMtiColumnsByVariant) : void 0;
|
|
2331
|
+
return {
|
|
2332
|
+
projectionState: {
|
|
2333
|
+
...state,
|
|
2334
|
+
selectedFields: selection.baseSelectedFields
|
|
2335
|
+
},
|
|
2336
|
+
joins: mtiArtifacts?.joins ?? [],
|
|
2337
|
+
projection: [...mtiArtifacts?.projection ?? [], ...buildHiddenDiscriminatorProjection(contract, root, polyInfo, selection.needsHiddenDiscriminator)]
|
|
2338
|
+
};
|
|
2339
|
+
}
|
|
2340
|
+
function compileSelect(contract, modelName, state) {
|
|
2250
2341
|
assertLockCompatible(state);
|
|
2251
2342
|
if (state.distinctOn !== void 0 && state.distinctOn.length > 0) assertDistinctOnCapability(contract, "distinctOn");
|
|
2252
|
-
const
|
|
2253
|
-
const
|
|
2254
|
-
|
|
2255
|
-
...state,
|
|
2256
|
-
selectedFields: selection.baseSelectedFields
|
|
2257
|
-
} : state;
|
|
2258
|
-
const mtiArtifacts = polyInfo && polyInfo.mtiVariants.length > 0 ? buildMtiJoins(contract, namespaceId, polyInfo, state.variantName, selection?.selectedMtiColumnsByTable) : void 0;
|
|
2259
|
-
const hiddenProjection = polyInfo && selection ? buildHiddenDiscriminatorProjection(contract, namespaceId, polyInfo, tableName, selection.needsHiddenDiscriminator) : [];
|
|
2260
|
-
const ast = buildSelectAst(contract, modelName, tableName, {
|
|
2261
|
-
...projectionState,
|
|
2343
|
+
const polymorphism = buildRootPolymorphism(contract, state, modelName);
|
|
2344
|
+
const ast = buildSelectAst(contract, modelName, {
|
|
2345
|
+
...polymorphism.projectionState,
|
|
2262
2346
|
includes: []
|
|
2263
2347
|
}, {
|
|
2264
|
-
joins:
|
|
2265
|
-
includeProjection:
|
|
2266
|
-
namespaceId
|
|
2348
|
+
joins: polymorphism.joins,
|
|
2349
|
+
includeProjection: polymorphism.projection
|
|
2267
2350
|
});
|
|
2268
2351
|
const { params } = deriveParamsFromAst(ast);
|
|
2269
2352
|
return buildOrmQueryPlan(contract, ast, params, state.annotations);
|
|
2270
2353
|
}
|
|
2271
|
-
function compileSelectWithIncludes(contract, aggregates,
|
|
2354
|
+
function compileSelectWithIncludes(contract, aggregates, modelName, state) {
|
|
2272
2355
|
assertLockCompatible(state);
|
|
2273
|
-
const
|
|
2274
|
-
const
|
|
2275
|
-
const
|
|
2276
|
-
const
|
|
2277
|
-
const
|
|
2278
|
-
const projectionState = selection ? {
|
|
2279
|
-
...state,
|
|
2280
|
-
selectedFields: selection.baseSelectedFields
|
|
2281
|
-
} : state;
|
|
2282
|
-
if (polyInfo && selection) {
|
|
2283
|
-
if (polyInfo.mtiVariants.length > 0) {
|
|
2284
|
-
const mtiArtifacts = buildMtiJoins(contract, namespaceId, polyInfo, state.variantName, selection.selectedMtiColumnsByTable);
|
|
2285
|
-
includeJoins.push(...mtiArtifacts.joins);
|
|
2286
|
-
includeProjection.push(...mtiArtifacts.projection);
|
|
2287
|
-
}
|
|
2288
|
-
includeProjection.push(...buildHiddenDiscriminatorProjection(contract, namespaceId, polyInfo, tableName, selection.needsHiddenDiscriminator));
|
|
2289
|
-
}
|
|
2290
|
-
const parentSource = {
|
|
2291
|
-
baseTableName: tableName,
|
|
2292
|
-
tableRef: tableName,
|
|
2293
|
-
variantColumnsProjected: false
|
|
2294
|
-
};
|
|
2356
|
+
const topLevelWhere = buildStateWhere(contract, state);
|
|
2357
|
+
const polymorphism = buildRootPolymorphism(contract, state, modelName);
|
|
2358
|
+
const includeProjection = [...polymorphism.projection];
|
|
2359
|
+
const scope = state.tables.scope.copy();
|
|
2360
|
+
const parent = { tables: state.tables };
|
|
2295
2361
|
for (const include of state.includes) {
|
|
2296
|
-
const artifact = buildCorrelatedIncludeProjection(contract, aggregates,
|
|
2362
|
+
const artifact = buildCorrelatedIncludeProjection(contract, aggregates, scope, parent, include);
|
|
2297
2363
|
includeProjection.push(artifact.projection);
|
|
2298
2364
|
}
|
|
2299
|
-
const ast = buildSelectAst(contract, modelName,
|
|
2300
|
-
...projectionState,
|
|
2365
|
+
const ast = buildSelectAst(contract, modelName, {
|
|
2366
|
+
...polymorphism.projectionState,
|
|
2301
2367
|
includes: []
|
|
2302
2368
|
}, {
|
|
2303
|
-
joins:
|
|
2369
|
+
joins: polymorphism.joins,
|
|
2304
2370
|
includeProjection,
|
|
2305
|
-
namespaceId,
|
|
2306
2371
|
...ifDefined("where", topLevelWhere)
|
|
2307
2372
|
});
|
|
2308
2373
|
const { params } = deriveParamsFromAst(ast);
|
|
@@ -2318,19 +2383,19 @@ function describeCollectionRows(options) {
|
|
|
2318
2383
|
};
|
|
2319
2384
|
}
|
|
2320
2385
|
function describeExecutionRows(options) {
|
|
2321
|
-
const { context, state,
|
|
2386
|
+
const { context, state, modelName, namespaceId } = options;
|
|
2322
2387
|
const { contract } = context;
|
|
2323
2388
|
const polyInfo = resolvePolymorphismInfo(contract, namespaceId, modelName);
|
|
2324
2389
|
if (state.includes.length === 0) {
|
|
2325
|
-
const compiled = compileSelect(contract,
|
|
2326
|
-
const mapper = polyInfo ? (rawRow) => blindCast(mapPolymorphicRow(contract, namespaceId, modelName, polyInfo, rawRow, state.variantName)) : (rawRow) => blindCast(mapStorageRowToModelFields(contract, namespaceId, modelName, rawRow));
|
|
2390
|
+
const compiled = compileSelect(contract, modelName, state);
|
|
2391
|
+
const mapper = polyInfo ? (rawRow) => blindCast(mapPolymorphicRow(contract, namespaceId, modelName, polyInfo, state.tables, rawRow, state.variantName)) : (rawRow) => blindCast(mapStorageRowToModelFields(contract, namespaceId, modelName, rawRow));
|
|
2327
2392
|
return {
|
|
2328
2393
|
plan: compiled,
|
|
2329
2394
|
consume: (rows) => mapResultRows(rows, mapper)
|
|
2330
2395
|
};
|
|
2331
2396
|
}
|
|
2332
2397
|
return {
|
|
2333
|
-
plan: compileSelectWithIncludes(contract, context.aggregateDescriptors,
|
|
2398
|
+
plan: compileSelectWithIncludes(contract, context.aggregateDescriptors, modelName, state),
|
|
2334
2399
|
consume: (rows) => consumeIncludeRows(context, state, namespaceId, modelName, rows)
|
|
2335
2400
|
};
|
|
2336
2401
|
}
|
|
@@ -2344,16 +2409,16 @@ function deferResolution(resolve) {
|
|
|
2344
2409
|
};
|
|
2345
2410
|
}
|
|
2346
2411
|
}
|
|
2347
|
-
function createPreparedMapper(contract, namespaceId, modelName,
|
|
2412
|
+
function createPreparedMapper(contract, namespaceId, modelName, state) {
|
|
2348
2413
|
const resolved = deferResolution(() => {
|
|
2349
2414
|
const polyInfo = resolvePolymorphismInfo(contract, namespaceId, modelName);
|
|
2350
|
-
return polyInfo ? createPolymorphicRowMapper(contract, namespaceId, modelName, polyInfo, variantName) : createStorageRowMapper(contract, namespaceId, modelName);
|
|
2415
|
+
return polyInfo ? createPolymorphicRowMapper(contract, namespaceId, modelName, polyInfo, state.tables, state.variantName) : createStorageRowMapper(contract, namespaceId, modelName);
|
|
2351
2416
|
});
|
|
2352
2417
|
return (row) => resolved()(row);
|
|
2353
2418
|
}
|
|
2354
2419
|
function createPreparedRowsConsumer(options) {
|
|
2355
2420
|
const { context, state, namespaceId, modelName } = options;
|
|
2356
|
-
const mapRow = createPreparedMapper(context.contract, namespaceId, modelName, state
|
|
2421
|
+
const mapRow = createPreparedMapper(context.contract, namespaceId, modelName, state);
|
|
2357
2422
|
const includes = state.includes.map((include) => createPreparedIncludeConsumer(context, include));
|
|
2358
2423
|
const castRow = (row) => blindCast(row);
|
|
2359
2424
|
if (includes.length === 0) return (rows) => mapResultRows(rows, (row) => castRow(mapRow(row)));
|
|
@@ -2393,12 +2458,15 @@ function createPreparedIncludeConsumer(context, include) {
|
|
|
2393
2458
|
}
|
|
2394
2459
|
};
|
|
2395
2460
|
}
|
|
2396
|
-
const mapRow = createPreparedMapper(contract, include.relatedNamespaceId, include.relatedModelName, include.nested
|
|
2461
|
+
const mapRow = createPreparedMapper(contract, include.relatedNamespaceId, include.relatedModelName, include.nested);
|
|
2397
2462
|
const bindings = deferResolution(() => {
|
|
2398
2463
|
const namespace = include.relatedNamespaceId;
|
|
2399
2464
|
const keys = new Set(getColumnsReadOnTable(contract, namespace, addressedModelName(include.relatedModelName, include.nested.variantName), include.relatedTableName));
|
|
2400
2465
|
const polyInfo = resolvePolymorphismInfo(contract, namespace, include.relatedModelName);
|
|
2401
|
-
for (const variant of polyInfo?.mtiVariants ?? [])
|
|
2466
|
+
for (const variant of polyInfo?.mtiVariants ?? []) {
|
|
2467
|
+
const variantTable = requireVariantTable(include.nested.tables, variant.modelName);
|
|
2468
|
+
for (const column of getColumnsReadOnTable(contract, variantTable.storage.namespaceId, variant.modelName, variantTable.storage.tableName)) keys.add(variantColumnLabel(variantTable, column));
|
|
2469
|
+
}
|
|
2402
2470
|
return new Map([...keys].map((key) => [key, deferResolution(() => resolveIncludedColumnBinding(contract, context, include, key))]));
|
|
2403
2471
|
});
|
|
2404
2472
|
const bindingFor = (key) => bindings().get(key)?.() ?? null;
|
|
@@ -2482,11 +2550,10 @@ function describeCollectionFirstOrThrow(options) {
|
|
|
2482
2550
|
};
|
|
2483
2551
|
}
|
|
2484
2552
|
function dispatchCollectionRows(options) {
|
|
2485
|
-
const { context, runtime, state,
|
|
2553
|
+
const { context, runtime, state, modelName, namespaceId } = options;
|
|
2486
2554
|
const descriptionOptions = {
|
|
2487
2555
|
context,
|
|
2488
2556
|
state,
|
|
2489
|
-
tableName,
|
|
2490
2557
|
modelName,
|
|
2491
2558
|
namespaceId
|
|
2492
2559
|
};
|
|
@@ -2510,7 +2577,7 @@ function consumeIncludeRows(context, state, namespaceId, modelName, rows) {
|
|
|
2510
2577
|
const parentRows = parentRowsRaw.map((row) => {
|
|
2511
2578
|
return {
|
|
2512
2579
|
raw: row,
|
|
2513
|
-
mapped: polyInfo ? mapPolymorphicRow(contract, namespaceId, modelName, polyInfo, row, state.variantName) : mapStorageRowToModelFields(contract, namespaceId, modelName, row)
|
|
2580
|
+
mapped: polyInfo ? mapPolymorphicRow(contract, namespaceId, modelName, polyInfo, state.tables, row, state.variantName) : mapStorageRowToModelFields(contract, namespaceId, modelName, row)
|
|
2514
2581
|
};
|
|
2515
2582
|
});
|
|
2516
2583
|
const bindings = /* @__PURE__ */ new WeakMap();
|
|
@@ -2538,26 +2605,26 @@ function consumeIncludeRows(context, state, namespaceId, modelName, rows) {
|
|
|
2538
2605
|
* its snapshot before issuing the DELETE (see `collection.ts`).
|
|
2539
2606
|
*/
|
|
2540
2607
|
function reloadMutationRowsByIdentities(options) {
|
|
2541
|
-
const { context, runtime,
|
|
2608
|
+
const { context, runtime, tables, modelName, namespaceId, identityRows, selectedFields, includes } = options;
|
|
2542
2609
|
const { contract } = context;
|
|
2610
|
+
const { tableName } = tables.root.storage;
|
|
2543
2611
|
if (identityRows.length === 0) return emptyResult();
|
|
2544
2612
|
const identityColumns = resolveRowIdentityColumns(contract, namespaceId, tableName);
|
|
2545
2613
|
if (identityColumns.length === 0) throw ormError("ORM.ROW_IDENTITY_MISSING", `Cannot load includes for the mutation result on model "${modelName}": table "${tableName}" has no primary key or unique constraint to key the include read-back on.`, { meta: {
|
|
2546
2614
|
model: modelName,
|
|
2547
2615
|
table: tableName
|
|
2548
2616
|
} });
|
|
2549
|
-
const identityFilter = buildIdentityInFilter(contract,
|
|
2617
|
+
const identityFilter = buildIdentityInFilter(contract, tables.root, identityColumns, identityRows);
|
|
2550
2618
|
if (!identityFilter) return emptyResult();
|
|
2551
2619
|
return dispatchCollectionRows({
|
|
2552
2620
|
context,
|
|
2553
2621
|
runtime,
|
|
2554
2622
|
state: {
|
|
2555
|
-
...emptyState(),
|
|
2623
|
+
...emptyState(tables),
|
|
2556
2624
|
filters: [identityFilter],
|
|
2557
2625
|
selectedFields,
|
|
2558
2626
|
includes
|
|
2559
2627
|
},
|
|
2560
|
-
tableName,
|
|
2561
2628
|
modelName,
|
|
2562
2629
|
namespaceId
|
|
2563
2630
|
});
|
|
@@ -2565,16 +2632,17 @@ function reloadMutationRowsByIdentities(options) {
|
|
|
2565
2632
|
function emptyResult() {
|
|
2566
2633
|
return new AsyncIterableResult((async function* () {})());
|
|
2567
2634
|
}
|
|
2568
|
-
function buildIdentityInFilter(contract,
|
|
2635
|
+
function buildIdentityInFilter(contract, table, identityColumns, identityRows) {
|
|
2636
|
+
const { storage } = table;
|
|
2569
2637
|
const [singleColumn, ...rest] = identityColumns;
|
|
2570
2638
|
if (singleColumn !== void 0 && rest.length === 0) {
|
|
2571
2639
|
const values = identityRows.map((row) => row[singleColumn]).filter((value) => value !== void 0);
|
|
2572
2640
|
if (values.length === 0) return;
|
|
2573
|
-
return
|
|
2641
|
+
return BinaryExpr.in(table.column(singleColumn), ListExpression.of(values.map((value) => paramRefForStorageColumn(contract, storage, singleColumn, value))));
|
|
2574
2642
|
}
|
|
2575
2643
|
if (identityRows.length === 0) return;
|
|
2576
|
-
const tuples = identityRows.map((row) => AndExpr.of(identityColumns.map((column) => BinaryExpr.eq(
|
|
2577
|
-
return
|
|
2644
|
+
const tuples = identityRows.map((row) => AndExpr.of(identityColumns.map((column) => BinaryExpr.eq(table.column(column), paramRefForStorageColumn(contract, storage, column, row[column])))));
|
|
2645
|
+
return OrExpr.of(tuples);
|
|
2578
2646
|
}
|
|
2579
2647
|
/**
|
|
2580
2648
|
* Decode a single-query include payload from a parent row's raw cell
|
|
@@ -2602,7 +2670,7 @@ function decodeIncludePayload(contract, context, include, raw, bindings) {
|
|
|
2602
2670
|
if (include.combine) return decodeCombineIncludePayload(contract, context, include, include.combine, raw, bindings);
|
|
2603
2671
|
const rawChildren = parseIncludedRows(include, raw);
|
|
2604
2672
|
const polyInfo = resolvePolymorphismInfo(contract, include.relatedNamespaceId, include.relatedModelName);
|
|
2605
|
-
const mapChildRow = polyInfo ? (childRow) => mapPolymorphicRow(contract, include.relatedNamespaceId, include.relatedModelName, polyInfo, childRow, include.nested.variantName) : createStorageRowMapper(contract, include.relatedNamespaceId, include.relatedModelName);
|
|
2673
|
+
const mapChildRow = polyInfo ? (childRow) => mapPolymorphicRow(contract, include.relatedNamespaceId, include.relatedModelName, polyInfo, include.nested.tables, childRow, include.nested.variantName) : createStorageRowMapper(contract, include.relatedNamespaceId, include.relatedModelName);
|
|
2606
2674
|
let columns = bindings.get(include);
|
|
2607
2675
|
if (!columns) {
|
|
2608
2676
|
columns = /* @__PURE__ */ new Map();
|
|
@@ -2646,17 +2714,18 @@ function decodeIncludedStorageRow(row, bindingFor) {
|
|
|
2646
2714
|
function resolveIncludedColumnBinding(contract, context, include, key) {
|
|
2647
2715
|
const ref = resolveIncludedColumnRef(contract, include, key);
|
|
2648
2716
|
if (!ref) return null;
|
|
2649
|
-
const codec = context.contractCodecs.forColumn(
|
|
2717
|
+
const codec = context.contractCodecs.forColumn(ref.namespaceId, ref.table, ref.column);
|
|
2650
2718
|
if (!codec) return null;
|
|
2651
2719
|
return {
|
|
2652
2720
|
ref,
|
|
2653
2721
|
codec,
|
|
2654
|
-
codecId: context.codecDescriptors.codecRefForColumn(
|
|
2722
|
+
codecId: context.codecDescriptors.codecRefForColumn(ref.namespaceId, ref.table, ref.column)?.codecId ?? ref.storageColumn.codecId
|
|
2655
2723
|
};
|
|
2656
2724
|
}
|
|
2657
2725
|
function resolveIncludedColumnRef(contract, include, key) {
|
|
2658
2726
|
const baseColumn = resolveColumn(contract, include.relatedNamespaceId, include.relatedTableName, key);
|
|
2659
2727
|
if (baseColumn) return {
|
|
2728
|
+
namespaceId: include.relatedNamespaceId,
|
|
2660
2729
|
table: include.relatedTableName,
|
|
2661
2730
|
column: key,
|
|
2662
2731
|
storageColumn: baseColumn
|
|
@@ -2664,12 +2733,15 @@ function resolveIncludedColumnRef(contract, include, key) {
|
|
|
2664
2733
|
const polyInfo = resolvePolymorphismInfo(contract, include.relatedNamespaceId, include.relatedModelName);
|
|
2665
2734
|
if (!polyInfo) return;
|
|
2666
2735
|
for (const variant of polyInfo.mtiVariants) {
|
|
2667
|
-
const
|
|
2736
|
+
const variantTable = requireVariantTable(include.nested.tables, variant.modelName);
|
|
2737
|
+
const prefix = variantColumnLabelPrefix(variantTable);
|
|
2668
2738
|
if (!key.startsWith(prefix)) continue;
|
|
2669
2739
|
const column = key.slice(prefix.length);
|
|
2670
|
-
const
|
|
2740
|
+
const { namespaceId, tableName } = variantTable.storage;
|
|
2741
|
+
const variantColumn = resolveColumn(contract, namespaceId, tableName, column);
|
|
2671
2742
|
if (variantColumn) return {
|
|
2672
|
-
|
|
2743
|
+
namespaceId,
|
|
2744
|
+
table: tableName,
|
|
2673
2745
|
column,
|
|
2674
2746
|
storageColumn: variantColumn
|
|
2675
2747
|
};
|
|
@@ -2830,14 +2902,14 @@ function parseIncludePayload(value) {
|
|
|
2830
2902
|
return [];
|
|
2831
2903
|
}
|
|
2832
2904
|
}
|
|
2833
|
-
function createMutationRowMapper(contract, namespaceId, modelName, variantName) {
|
|
2905
|
+
function createMutationRowMapper(contract, namespaceId, modelName, tables, variantName) {
|
|
2834
2906
|
const polyInfo = resolvePolymorphismInfo(contract, namespaceId, modelName);
|
|
2835
|
-
return polyInfo ? (row) => mapPolymorphicRow(contract, namespaceId, modelName, polyInfo, row, variantName) : (row) => mapStorageRowToModelFields(contract, namespaceId, modelName, row);
|
|
2907
|
+
return polyInfo ? (row) => mapPolymorphicRow(contract, namespaceId, modelName, polyInfo, tables, row, variantName) : (row) => mapStorageRowToModelFields(contract, namespaceId, modelName, row);
|
|
2836
2908
|
}
|
|
2837
2909
|
function dispatchMutationRows(options) {
|
|
2838
|
-
const { context, runtime, compiled,
|
|
2910
|
+
const { context, runtime, compiled, tables, modelName, namespaceId, variantName, includes, selectedFields, hiddenColumns, mapRow } = options;
|
|
2839
2911
|
const { contract } = context;
|
|
2840
|
-
const mapStorageRow = createMutationRowMapper(contract, namespaceId, modelName, variantName);
|
|
2912
|
+
const mapStorageRow = createMutationRowMapper(contract, namespaceId, modelName, tables, variantName);
|
|
2841
2913
|
if (includes.length === 0) return mapResultRows(queryPlanRows(runtime, compiled), (rawRow) => {
|
|
2842
2914
|
const mapped = mapStorageRow(rawRow);
|
|
2843
2915
|
if (hiddenColumns.length > 0) stripHiddenMappedFields(contract, namespaceId, modelName, mapped, hiddenColumns);
|
|
@@ -2848,7 +2920,7 @@ function dispatchMutationRows(options) {
|
|
|
2848
2920
|
yield* reloadMutationRowsByIdentities({
|
|
2849
2921
|
context,
|
|
2850
2922
|
runtime,
|
|
2851
|
-
|
|
2923
|
+
tables,
|
|
2852
2924
|
modelName,
|
|
2853
2925
|
namespaceId,
|
|
2854
2926
|
identityRows,
|
|
@@ -2859,9 +2931,9 @@ function dispatchMutationRows(options) {
|
|
|
2859
2931
|
return new AsyncIterableResult(generator());
|
|
2860
2932
|
}
|
|
2861
2933
|
function dispatchSplitMutationRows(options) {
|
|
2862
|
-
const { context, runtime, plans,
|
|
2934
|
+
const { context, runtime, plans, tables, modelName, namespaceId, variantName, includes, selectedFields, hiddenColumns, mapRow } = options;
|
|
2863
2935
|
const { contract } = context;
|
|
2864
|
-
const mapStorageRow = createMutationRowMapper(contract, namespaceId, modelName, variantName);
|
|
2936
|
+
const mapStorageRow = createMutationRowMapper(contract, namespaceId, modelName, tables, variantName);
|
|
2865
2937
|
const generator = async function* () {
|
|
2866
2938
|
if (includes.length > 0) {
|
|
2867
2939
|
const identityRows = [];
|
|
@@ -2869,7 +2941,7 @@ function dispatchSplitMutationRows(options) {
|
|
|
2869
2941
|
yield* reloadMutationRowsByIdentities({
|
|
2870
2942
|
context,
|
|
2871
2943
|
runtime,
|
|
2872
|
-
|
|
2944
|
+
tables,
|
|
2873
2945
|
modelName,
|
|
2874
2946
|
namespaceId,
|
|
2875
2947
|
identityRows,
|
|
@@ -2887,9 +2959,9 @@ function dispatchSplitMutationRows(options) {
|
|
|
2887
2959
|
return new AsyncIterableResult(generator());
|
|
2888
2960
|
}
|
|
2889
2961
|
async function executeMutationReturningSingleRow(options) {
|
|
2890
|
-
const { context, runtime, compiled,
|
|
2962
|
+
const { context, runtime, compiled, tables, modelName, namespaceId, variantName, includes, selectedFields, hiddenColumns, mapRow, operation, onMissingRowMessage } = options;
|
|
2891
2963
|
const { contract } = context;
|
|
2892
|
-
const mapStorageRow = createMutationRowMapper(contract, namespaceId, modelName, variantName);
|
|
2964
|
+
const mapStorageRow = createMutationRowMapper(contract, namespaceId, modelName, tables, variantName);
|
|
2893
2965
|
if (includes.length === 0) {
|
|
2894
2966
|
const first = (await queryPlanRows(runtime, compiled).toArray())[0];
|
|
2895
2967
|
if (!first) return null;
|
|
@@ -2902,7 +2974,7 @@ async function executeMutationReturningSingleRow(options) {
|
|
|
2902
2974
|
for await (const row of reloadMutationRowsByIdentities({
|
|
2903
2975
|
context,
|
|
2904
2976
|
runtime,
|
|
2905
|
-
|
|
2977
|
+
tables,
|
|
2906
2978
|
modelName,
|
|
2907
2979
|
namespaceId,
|
|
2908
2980
|
identityRows,
|
|
@@ -2912,7 +2984,7 @@ async function executeMutationReturningSingleRow(options) {
|
|
|
2912
2984
|
throw ormError("ORM.MUTATION_ROW_MISSING", onMissingRowMessage, { meta: {
|
|
2913
2985
|
operation,
|
|
2914
2986
|
model: modelName,
|
|
2915
|
-
tableName
|
|
2987
|
+
tableName: tables.root.storage.tableName
|
|
2916
2988
|
} });
|
|
2917
2989
|
}
|
|
2918
2990
|
/** The filter expression of a condition: a condition from `fns` becomes its AST. */
|
|
@@ -2938,20 +3010,20 @@ function not(expr) {
|
|
|
2938
3010
|
function all() {
|
|
2939
3011
|
return AndExpr.true();
|
|
2940
3012
|
}
|
|
2941
|
-
function shorthandToWhereExpr(context, namespaceId, modelName, filters) {
|
|
3013
|
+
function shorthandToWhereExpr(context, namespaceId, modelName, filters, table) {
|
|
2942
3014
|
const contract = context.contract;
|
|
2943
|
-
const tableName = resolveModelTableName(contract, namespaceId, modelName);
|
|
2944
3015
|
const fieldColumns = getModelFieldColumns(contract, namespaceId, modelName);
|
|
2945
3016
|
const exprs = [];
|
|
2946
3017
|
for (const [fieldName, value] of Object.entries(filters)) {
|
|
2947
3018
|
if (value === void 0) continue;
|
|
2948
|
-
const
|
|
3019
|
+
const columnName = columnOfCallerField(contract, namespaceId, fieldColumns, modelName, fieldName);
|
|
3020
|
+
const left = table.column(columnName);
|
|
2949
3021
|
if (value === null) {
|
|
2950
3022
|
exprs.push(NullCheckExpr.isNull(left));
|
|
2951
3023
|
continue;
|
|
2952
3024
|
}
|
|
2953
3025
|
assertFieldHasEqualityTrait(context, namespaceId, modelName, fieldName);
|
|
2954
|
-
exprs.push(predicateComparison("eq", left, predicateExpression(value) ??
|
|
3026
|
+
exprs.push(predicateComparison("eq", left, predicateExpression(value) ?? paramRefForStorageColumn(contract, table.storage, columnName, value)));
|
|
2955
3027
|
}
|
|
2956
3028
|
if (exprs.length === 0) return;
|
|
2957
3029
|
return exprs.length === 1 ? exprs[0] : and(...exprs);
|
|
@@ -3419,103 +3491,21 @@ function createCallbackTools(context, indexes) {
|
|
|
3419
3491
|
function hasThrough$1(relation) {
|
|
3420
3492
|
return relation.through !== void 0;
|
|
3421
3493
|
}
|
|
3422
|
-
|
|
3423
|
-
|
|
3424
|
-
#reference;
|
|
3425
|
-
constructor(storage, reference) {
|
|
3426
|
-
this.#storage = Object.freeze({ ...storage });
|
|
3427
|
-
this.#reference = reference;
|
|
3428
|
-
Object.freeze(this);
|
|
3429
|
-
}
|
|
3430
|
-
static unaliased(storage) {
|
|
3431
|
-
return new SqlTableBinding(storage, storage.tableName);
|
|
3432
|
-
}
|
|
3433
|
-
static aliased(storage, alias) {
|
|
3434
|
-
return new SqlTableBinding(storage, alias);
|
|
3435
|
-
}
|
|
3436
|
-
column(columnName) {
|
|
3437
|
-
return ColumnRef.of(this.#reference, columnName);
|
|
3438
|
-
}
|
|
3439
|
-
tableSource(contract) {
|
|
3440
|
-
return tableSourceForContract(contract, this.#storage.namespaceId, this.#storage.tableName, this.#reference);
|
|
3441
|
-
}
|
|
3442
|
-
isReferencedAs(candidate) {
|
|
3443
|
-
return this.#reference === candidate;
|
|
3444
|
-
}
|
|
3445
|
-
isStoredAt(namespaceId, tableName) {
|
|
3446
|
-
return this.#storage.namespaceId === namespaceId && this.#storage.tableName === tableName;
|
|
3447
|
-
}
|
|
3448
|
-
};
|
|
3449
|
-
var ModelAccessorScope = class ModelAccessorScope {
|
|
3450
|
-
current;
|
|
3451
|
-
#visibleBindings;
|
|
3452
|
-
#aliasCounter;
|
|
3453
|
-
constructor(current, visibleBindings, aliasCounter) {
|
|
3454
|
-
this.current = current;
|
|
3455
|
-
this.#visibleBindings = Object.freeze([...visibleBindings]);
|
|
3456
|
-
this.#aliasCounter = aliasCounter;
|
|
3457
|
-
Object.freeze(this);
|
|
3458
|
-
}
|
|
3459
|
-
static root(namespaceId, tableName) {
|
|
3460
|
-
const binding = SqlTableBinding.unaliased({
|
|
3461
|
-
namespaceId,
|
|
3462
|
-
tableName
|
|
3463
|
-
});
|
|
3464
|
-
return new ModelAccessorScope(binding, [binding], { nextId: 1 });
|
|
3465
|
-
}
|
|
3466
|
-
forRelation(namespaceId, tableName) {
|
|
3467
|
-
const binding = this.#allocateBinding(namespaceId, tableName, "rel");
|
|
3468
|
-
return new ModelAccessorScope(binding, [...this.#visibleBindings, binding], this.#aliasCounter);
|
|
3469
|
-
}
|
|
3470
|
-
forManyToManyRelation(childNamespaceId, childTableName, junctionNamespaceId, junctionTableName) {
|
|
3471
|
-
const initialChildScope = this.forRelation(childNamespaceId, childTableName);
|
|
3472
|
-
const junctionBinding = initialChildScope.#allocateBinding(junctionNamespaceId, junctionTableName, "junction");
|
|
3473
|
-
return {
|
|
3474
|
-
childScope: new ModelAccessorScope(initialChildScope.current, [...initialChildScope.#visibleBindings, junctionBinding], this.#aliasCounter),
|
|
3475
|
-
junctionBinding
|
|
3476
|
-
};
|
|
3477
|
-
}
|
|
3478
|
-
forJoinedSource(namespaceId, tableName) {
|
|
3479
|
-
if (this.current.isStoredAt(namespaceId, tableName)) return this;
|
|
3480
|
-
const binding = SqlTableBinding.unaliased({
|
|
3481
|
-
namespaceId,
|
|
3482
|
-
tableName
|
|
3483
|
-
});
|
|
3484
|
-
return new ModelAccessorScope(binding, [...this.#visibleBindings, binding], this.#aliasCounter);
|
|
3485
|
-
}
|
|
3486
|
-
#allocateBinding(namespaceId, tableName, aliasKind) {
|
|
3487
|
-
const storage = {
|
|
3488
|
-
namespaceId,
|
|
3489
|
-
tableName
|
|
3490
|
-
};
|
|
3491
|
-
if (!this.#visibleBindings.some((binding) => binding.isReferencedAs(tableName))) return SqlTableBinding.unaliased(storage);
|
|
3492
|
-
return SqlTableBinding.aliased(storage, this.#allocateAlias(aliasKind));
|
|
3493
|
-
}
|
|
3494
|
-
#allocateAlias(kind) {
|
|
3495
|
-
while (true) {
|
|
3496
|
-
const alias = `__orm_${kind}_${this.#aliasCounter.nextId}`;
|
|
3497
|
-
this.#aliasCounter.nextId += 1;
|
|
3498
|
-
if (!this.#visibleBindings.some((binding) => binding.isReferencedAs(alias))) return alias;
|
|
3499
|
-
}
|
|
3500
|
-
}
|
|
3501
|
-
};
|
|
3502
|
-
function createModelAccessor(context, namespaceId, modelName, variantName) {
|
|
3503
|
-
const tableName = resolveModelTableName(context.contract, namespaceId, modelName);
|
|
3504
|
-
return createModelAccessorInScope(context, namespaceId, modelName, variantName, ModelAccessorScope.root(namespaceId, tableName));
|
|
3494
|
+
function createModelAccessor(context, namespaceId, modelName, tables, variantName) {
|
|
3495
|
+
return createModelAccessorInScope(context, namespaceId, modelName, variantName, tables.scope, tables.root, variantName === void 0 ? void 0 : tables.variants.get(variantName));
|
|
3505
3496
|
}
|
|
3506
3497
|
/**
|
|
3507
3498
|
* The second argument of a `where` or `orderBy` callback on a collection of the model: the SQL query builder's functions, and the indexes of the model's table.
|
|
3508
3499
|
*/
|
|
3509
|
-
function createModelCallbackTools(context,
|
|
3510
|
-
|
|
3511
|
-
return callbackToolsFor(context, namespaceId, modelName, ModelAccessorScope.root(namespaceId, tableName));
|
|
3500
|
+
function createModelCallbackTools(context, modelName, tables) {
|
|
3501
|
+
return callbackToolsFor(context, modelName, tables.root);
|
|
3512
3502
|
}
|
|
3513
|
-
function callbackToolsFor(context,
|
|
3514
|
-
return createCallbackTools(context, () => indexReferencesOf(context,
|
|
3503
|
+
function callbackToolsFor(context, modelName, aliasedTable) {
|
|
3504
|
+
return createCallbackTools(context, () => indexReferencesOf(context, modelName, aliasedTable));
|
|
3515
3505
|
}
|
|
3516
|
-
function indexReferencesOf(context,
|
|
3506
|
+
function indexReferencesOf(context, modelName, aliasedTable) {
|
|
3517
3507
|
const { contract } = context;
|
|
3518
|
-
const tableName =
|
|
3508
|
+
const { namespaceId, tableName } = aliasedTable.storage;
|
|
3519
3509
|
const resolved = resolveTableForContract(contract, namespaceId, tableName);
|
|
3520
3510
|
if (!resolved) throw new InternalError(`Model "${modelName}" is stored in table "${tableName}", which the contract does not have`);
|
|
3521
3511
|
const { table } = resolved;
|
|
@@ -3532,22 +3522,21 @@ function indexReferencesOf(context, namespaceId, modelName, binding) {
|
|
|
3532
3522
|
nullable: column.nullable,
|
|
3533
3523
|
...ifDefined("codec", codecRefForStorageColumn(contract.storage, namespaceId, tableName, columnName))
|
|
3534
3524
|
},
|
|
3535
|
-
buildAst: () =>
|
|
3525
|
+
buildAst: () => aliasedTable.column(columnName)
|
|
3536
3526
|
};
|
|
3537
3527
|
}
|
|
3538
3528
|
});
|
|
3539
3529
|
}
|
|
3540
|
-
function createModelAccessorInScope(context, namespaceId, modelName, variantName, scope) {
|
|
3530
|
+
function createModelAccessorInScope(context, namespaceId, modelName, variantName, scope, table, variantTable) {
|
|
3541
3531
|
const contract = context.contract;
|
|
3542
3532
|
const fieldColumns = getModelAndVariantFieldColumns(contract, namespaceId, modelName, variantName);
|
|
3543
|
-
const tableName = resolveModelTableName(contract, namespaceId, modelName);
|
|
3544
3533
|
const modelRelations = resolveModelRelations(contract, namespaceId, modelName);
|
|
3545
3534
|
const variantFieldColumns = variantName ? resolveVariantFieldColumns(contract, namespaceId, modelName, variantName) : {};
|
|
3546
3535
|
const variantCoordinates = variantName ? {
|
|
3547
3536
|
name: variantName,
|
|
3548
|
-
relations: resolveModelRelations(contract, namespaceId, variantName)
|
|
3549
|
-
tableName: resolvePolymorphismInfo(contract, namespaceId, modelName)?.variants.get(variantName)?.table ?? tableName
|
|
3537
|
+
relations: resolveModelRelations(contract, namespaceId, variantName)
|
|
3550
3538
|
} : void 0;
|
|
3539
|
+
const variantFieldTable = variantTable ?? table;
|
|
3551
3540
|
const opsByCodecId = /* @__PURE__ */ new Map();
|
|
3552
3541
|
function registerOp(codecId, op) {
|
|
3553
3542
|
let existing = opsByCodecId.get(codecId);
|
|
@@ -3571,27 +3560,27 @@ function createModelAccessorInScope(context, namespaceId, modelName, variantName
|
|
|
3571
3560
|
if (typeof prop !== "string") return;
|
|
3572
3561
|
if (variantCoordinates && Object.hasOwn(variantCoordinates.relations, prop)) {
|
|
3573
3562
|
const variantRelation = variantCoordinates.relations[prop];
|
|
3574
|
-
if (variantRelation) return createRelationFilterAccessor(context, namespaceId, variantCoordinates.name, scope
|
|
3563
|
+
if (variantRelation) return createRelationFilterAccessor(context, namespaceId, variantCoordinates.name, scope, variantFieldTable, variantRelation);
|
|
3575
3564
|
}
|
|
3576
3565
|
const relation = Object.hasOwn(modelRelations, prop) ? modelRelations[prop] : void 0;
|
|
3577
|
-
if (relation) return createRelationFilterAccessor(context, namespaceId, modelName, scope, relation);
|
|
3566
|
+
if (relation) return createRelationFilterAccessor(context, namespaceId, modelName, scope, table, relation);
|
|
3578
3567
|
const variantField = Object.hasOwn(variantFieldColumns, prop) ? variantFieldColumns[prop] : void 0;
|
|
3579
3568
|
if (variantField === void 0 && !Object.hasOwn(fieldColumns, prop)) {
|
|
3580
3569
|
if (isProbedByRuntime(prop)) return probedValue(target, prop);
|
|
3581
3570
|
}
|
|
3582
|
-
const
|
|
3583
|
-
const
|
|
3571
|
+
const fieldTable = variantField ? variantFieldTable : table;
|
|
3572
|
+
const fieldStorage = fieldTable.storage;
|
|
3584
3573
|
const columnName = variantField?.column ?? columnOfCallerField(contract, namespaceId, fieldColumns, addressedModelName(modelName, variantName), prop);
|
|
3585
|
-
const column = resolveColumn(contract, namespaceId,
|
|
3586
|
-
if (!column) throw new InternalError(`Field "${modelName}.${prop}" maps column "${columnName}", which table "${
|
|
3574
|
+
const column = resolveColumn(contract, fieldStorage.namespaceId, fieldStorage.tableName, columnName);
|
|
3575
|
+
if (!column) throw new InternalError(`Field "${modelName}.${prop}" maps column "${columnName}", which table "${fieldStorage.tableName}" does not have`);
|
|
3587
3576
|
const traits = codecTraits(context, column.codecId);
|
|
3588
3577
|
const operations = opsByCodecId.get(column.codecId) ?? [];
|
|
3589
|
-
const codec = codecRefForStorageColumn(contract.storage, namespaceId,
|
|
3590
|
-
return createScalarFieldAccessor(
|
|
3578
|
+
const codec = codecRefForStorageColumn(contract.storage, fieldStorage.namespaceId, fieldStorage.tableName, columnName);
|
|
3579
|
+
return createScalarFieldAccessor(fieldTable, columnName, column.codecId, column.nullable, codec, traits, operations, context);
|
|
3591
3580
|
} }));
|
|
3592
3581
|
}
|
|
3593
|
-
function createScalarFieldAccessor(
|
|
3594
|
-
const column =
|
|
3582
|
+
function createScalarFieldAccessor(table, columnName, codecId, nullable, codec, traits, operations, context) {
|
|
3583
|
+
const column = table.column(columnName);
|
|
3595
3584
|
const comparisonEntries = [];
|
|
3596
3585
|
for (const [name, meta] of Object.entries(COMPARISON_METHODS_META)) {
|
|
3597
3586
|
if (meta.traits.some((t) => !traits.includes(t))) continue;
|
|
@@ -3631,13 +3620,13 @@ const RELATION_ACCESSOR_METHOD_NAMES = /* @__PURE__ */ new Set([
|
|
|
3631
3620
|
"none",
|
|
3632
3621
|
"count"
|
|
3633
3622
|
]);
|
|
3634
|
-
function createRelationFilterAccessor(context, parentNamespaceId, parentModelName,
|
|
3623
|
+
function createRelationFilterAccessor(context, parentNamespaceId, parentModelName, scope, parentTable, relation) {
|
|
3635
3624
|
const relatedTableName = resolveModelTableName(context.contract, relation.toNamespace, relation.to);
|
|
3636
|
-
const correlate = () => correlateRelatedRows(context, parentNamespaceId, parentModelName,
|
|
3625
|
+
const correlate = () => correlateRelatedRows(context, parentNamespaceId, parentModelName, scope, parentTable, relatedTableName, relation);
|
|
3637
3626
|
const filters = {
|
|
3638
|
-
some: (predicate) => buildExistsExpr(context, relation, correlate(), "some", predicate),
|
|
3639
|
-
every: (predicate) => buildExistsExpr(context, relation, correlate(), "every", predicate),
|
|
3640
|
-
none: (predicate) => buildExistsExpr(context, relation, correlate(), "none", predicate)
|
|
3627
|
+
some: (predicate) => buildExistsExpr(context, relation, scope, correlate(), "some", predicate),
|
|
3628
|
+
every: (predicate) => buildExistsExpr(context, relation, scope, correlate(), "every", predicate),
|
|
3629
|
+
none: (predicate) => buildExistsExpr(context, relation, scope, correlate(), "none", predicate)
|
|
3641
3630
|
};
|
|
3642
3631
|
if (isToOneCardinality(relation.cardinality)) return new Proxy(filters, { get(target, prop) {
|
|
3643
3632
|
if (typeof prop !== "string") return void 0;
|
|
@@ -3648,7 +3637,7 @@ function createRelationFilterAccessor(context, parentNamespaceId, parentModelNam
|
|
|
3648
3637
|
} });
|
|
3649
3638
|
return {
|
|
3650
3639
|
...filters,
|
|
3651
|
-
count: (predicate) => createOrderable(() => buildRelationCountExpr(context, relation, correlate(), predicate))
|
|
3640
|
+
count: (predicate) => createOrderable(() => buildRelationCountExpr(context, relation, scope, correlate(), predicate))
|
|
3652
3641
|
};
|
|
3653
3642
|
}
|
|
3654
3643
|
/**
|
|
@@ -3672,39 +3661,45 @@ function relatedOrderableField(context, relation, relatedTableName, correlate, f
|
|
|
3672
3661
|
if (!column || !hasTrait(context, column.codecId, "order")) return void 0;
|
|
3673
3662
|
return createOrderable(() => {
|
|
3674
3663
|
const rows = correlate();
|
|
3675
|
-
return SubqueryExpr.of(rows.source.withProjection([ProjectionItem.of(columnName, rows.
|
|
3664
|
+
return SubqueryExpr.of(rows.source.withProjection([ProjectionItem.of(columnName, rows.child.column(columnName))]).withWhere(rows.correlation));
|
|
3676
3665
|
});
|
|
3677
3666
|
}
|
|
3678
|
-
function buildRelationCountExpr(context, relation, rows, predicate) {
|
|
3679
|
-
const childWhere = toRelationWhereExpr(context, relation.toNamespace, relation.to, predicate, rows.
|
|
3667
|
+
function buildRelationCountExpr(context, relation, scope, rows, predicate) {
|
|
3668
|
+
const childWhere = toRelationWhereExpr(context, relation.toNamespace, relation.to, predicate, scope, rows.child);
|
|
3680
3669
|
return SubqueryExpr.of(rows.source.withProjection([ProjectionItem.of("count", plainAggregateExpr("count", void 0))]).withWhere(childWhere ? and(rows.correlation, childWhere) : rows.correlation));
|
|
3681
3670
|
}
|
|
3682
|
-
function correlateRelatedRows(context, parentNamespaceId, parentModelName,
|
|
3671
|
+
function correlateRelatedRows(context, parentNamespaceId, parentModelName, scope, parentTable, relatedTableName, relation) {
|
|
3672
|
+
const child = scope.aliasTable({
|
|
3673
|
+
namespaceId: relation.toNamespace,
|
|
3674
|
+
tableName: relatedTableName
|
|
3675
|
+
});
|
|
3683
3676
|
if (hasThrough$1(relation)) {
|
|
3684
3677
|
const { through } = relation;
|
|
3685
|
-
const
|
|
3686
|
-
|
|
3678
|
+
const junction = scope.aliasTable({
|
|
3679
|
+
namespaceId: through.namespaceId,
|
|
3680
|
+
tableName: through.table
|
|
3681
|
+
});
|
|
3682
|
+
const junctionJoinOn = buildPairedColumnExprs(junction, through.childColumns, child, through.targetColumns);
|
|
3687
3683
|
const parentLocalColumns = relation.on.localFields.map((field) => columnOfContractField(context.contract, parentNamespaceId, parentModelName, field));
|
|
3688
3684
|
return {
|
|
3689
|
-
|
|
3690
|
-
source: SelectAst.from(
|
|
3691
|
-
correlation: buildPairedColumnExprs(
|
|
3685
|
+
child,
|
|
3686
|
+
source: SelectAst.from(child.tableSource(context.contract)).withJoins([JoinAst.inner(junction.tableSource(context.contract), junctionJoinOn)]),
|
|
3687
|
+
correlation: buildPairedColumnExprs(junction, through.parentColumns, parentTable, parentLocalColumns),
|
|
3692
3688
|
keyColumn: firstJoinColumn(through.targetColumns, "targetColumns")
|
|
3693
3689
|
};
|
|
3694
3690
|
}
|
|
3695
|
-
const childScope = parentScope.forRelation(relation.toNamespace, relatedTableName);
|
|
3696
3691
|
return {
|
|
3697
|
-
|
|
3698
|
-
source: SelectAst.from(
|
|
3699
|
-
correlation: buildJoinWhere(context.contract, parentNamespaceId, parentModelName,
|
|
3692
|
+
child,
|
|
3693
|
+
source: SelectAst.from(child.tableSource(context.contract)),
|
|
3694
|
+
correlation: buildJoinWhere(context.contract, parentNamespaceId, parentModelName, parentTable, child, relation),
|
|
3700
3695
|
keyColumn: firstJoinColumn(resolveRelationTargetColumns(context.contract, relation), "targetFields")
|
|
3701
3696
|
};
|
|
3702
3697
|
}
|
|
3703
|
-
function buildExistsExpr(context, relation, rows, mode, predicate) {
|
|
3704
|
-
const childWhere = toRelationWhereExpr(context, relation.toNamespace, relation.to, predicate, rows.
|
|
3698
|
+
function buildExistsExpr(context, relation, scope, rows, mode, predicate) {
|
|
3699
|
+
const childWhere = toRelationWhereExpr(context, relation.toNamespace, relation.to, predicate, scope, rows.child);
|
|
3705
3700
|
const filterPlan = planRelationFilterMode(rows.correlation, childWhere, mode);
|
|
3706
3701
|
if (filterPlan.kind === "constantTrue") return AndExpr.true();
|
|
3707
|
-
const subquery = rows.source.withProjection([ProjectionItem.of("_exists", rows.
|
|
3702
|
+
const subquery = rows.source.withProjection([ProjectionItem.of("_exists", rows.child.column(rows.keyColumn))]).withWhere(filterPlan.where);
|
|
3708
3703
|
return filterPlan.notExists ? ExistsExpr.notExists(subquery) : ExistsExpr.exists(subquery);
|
|
3709
3704
|
}
|
|
3710
3705
|
function planRelationFilterMode(joinWhere, childWhere, mode) {
|
|
@@ -3745,10 +3740,10 @@ function buildPairedColumnExprs(leftTable, leftColumns, rightTable, rightColumns
|
|
|
3745
3740
|
if (exprs.length === 1 && exprs[0]) return exprs[0];
|
|
3746
3741
|
return and(...exprs);
|
|
3747
3742
|
}
|
|
3748
|
-
function toRelationWhereExpr(context, relatedNamespaceId, relatedModelName, predicate, scope) {
|
|
3743
|
+
function toRelationWhereExpr(context, relatedNamespaceId, relatedModelName, predicate, scope, table) {
|
|
3749
3744
|
if (!predicate) return;
|
|
3750
|
-
const accessor = createModelAccessorInScope(context, relatedNamespaceId, relatedModelName, void 0, scope);
|
|
3751
|
-
if (typeof predicate === "function") return conditionExpr(predicate(accessor, callbackToolsFor(context,
|
|
3745
|
+
const accessor = createModelAccessorInScope(context, relatedNamespaceId, relatedModelName, void 0, scope, table, void 0);
|
|
3746
|
+
if (typeof predicate === "function") return conditionExpr(predicate(accessor, callbackToolsFor(context, relatedModelName, table)));
|
|
3752
3747
|
assertModelFieldNames(context.contract, relatedNamespaceId, relatedModelName, predicate);
|
|
3753
3748
|
const exprs = [];
|
|
3754
3749
|
for (const [fieldName, value] of Object.entries(predicate)) {
|
|
@@ -3824,7 +3819,7 @@ var GroupedCollection = class GroupedCollection {
|
|
|
3824
3819
|
}));
|
|
3825
3820
|
}
|
|
3826
3821
|
having(predicate) {
|
|
3827
|
-
const havingExpr = predicate(createHavingBuilder(this.contract, this.ctx.context.aggregateDescriptors, this.namespaceId, this.modelName, this.
|
|
3822
|
+
const havingExpr = predicate(createHavingBuilder(this.contract, this.ctx.context.aggregateDescriptors, this.namespaceId, this.modelName, this.preGroupState.tables.root));
|
|
3828
3823
|
return this.#clone({ havingFilters: [...this.havingFilters, havingExpr] });
|
|
3829
3824
|
}
|
|
3830
3825
|
/**
|
|
@@ -3839,12 +3834,19 @@ var GroupedCollection = class GroupedCollection {
|
|
|
3839
3834
|
method: "orderBy",
|
|
3840
3835
|
model: this.modelName
|
|
3841
3836
|
} });
|
|
3842
|
-
const
|
|
3837
|
+
const tables = withScopeCopy(this.preGroupState.tables);
|
|
3838
|
+
const accessor = createModelAccessor(this.ctx.context, this.namespaceId, this.modelName, tables);
|
|
3843
3839
|
const nextOrders = selectors.map((selector) => selector(accessor));
|
|
3844
|
-
return this.#clone({
|
|
3845
|
-
|
|
3846
|
-
|
|
3847
|
-
|
|
3840
|
+
return this.#clone({
|
|
3841
|
+
preGroupState: {
|
|
3842
|
+
...this.preGroupState,
|
|
3843
|
+
tables
|
|
3844
|
+
},
|
|
3845
|
+
postGroup: {
|
|
3846
|
+
...this.postGroup,
|
|
3847
|
+
orderBy: [...this.postGroup.orderBy, ...nextOrders]
|
|
3848
|
+
}
|
|
3849
|
+
});
|
|
3848
3850
|
}
|
|
3849
3851
|
/**
|
|
3850
3852
|
* Apply `LIMIT n` to the grouped rows. Replaces any previous post-group
|
|
@@ -3900,7 +3902,7 @@ var GroupedCollection = class GroupedCollection {
|
|
|
3900
3902
|
configure(meta);
|
|
3901
3903
|
if (meta.annotations.size > 0) annotationsMap = meta.annotations;
|
|
3902
3904
|
}
|
|
3903
|
-
const compiled = mergeAnnotations(compileGroupedAggregate(this.contract, this.ctx.context.aggregateDescriptors, this.
|
|
3905
|
+
const compiled = mergeAnnotations(compileGroupedAggregate(this.contract, this.ctx.context.aggregateDescriptors, this.preGroupState, this.groupByColumns, aggregateSpec, combineWhereExprs(this.havingFilters), this.modelName, this.postGroup), annotationsMap);
|
|
3904
3906
|
const mapRow = createStorageRowMapper(this.contract, this.namespaceId, this.modelName);
|
|
3905
3907
|
return {
|
|
3906
3908
|
plan: compiled,
|
|
@@ -3924,7 +3926,8 @@ var GroupedCollection = class GroupedCollection {
|
|
|
3924
3926
|
* refused. The typed surface already excludes it; the runtime refusal covers
|
|
3925
3927
|
* dynamic invocation.
|
|
3926
3928
|
*/
|
|
3927
|
-
function createHavingBuilder(contract, aggregates, namespaceId, modelName,
|
|
3929
|
+
function createHavingBuilder(contract, aggregates, namespaceId, modelName, root) {
|
|
3930
|
+
const { tableName } = root.storage;
|
|
3928
3931
|
const fieldColumns = getModelFieldColumns(contract, namespaceId, modelName);
|
|
3929
3932
|
const builder = {};
|
|
3930
3933
|
for (const operation of aggregateOperationNames(aggregates)) builder[operation] = (field) => {
|
|
@@ -3934,7 +3937,7 @@ function createHavingBuilder(contract, aggregates, namespaceId, modelName, table
|
|
|
3934
3937
|
meta: { operation }
|
|
3935
3938
|
});
|
|
3936
3939
|
const column = field === void 0 ? void 0 : columnOfCallerField(contract, namespaceId, fieldColumns, modelName, field);
|
|
3937
|
-
return createHavingComparisonMethods(new AggregateExpr(operation, column === void 0 ? void 0 :
|
|
3940
|
+
return createHavingComparisonMethods(new AggregateExpr(operation, column === void 0 ? void 0 : root.column(column)), () => resolveAggregate({
|
|
3938
3941
|
aggregates,
|
|
3939
3942
|
contract,
|
|
3940
3943
|
namespaceId,
|
|
@@ -4054,7 +4057,7 @@ async function executeNestedCreateMutation(options) {
|
|
|
4054
4057
|
return withMutationScope(options.runtime, async (scope) => createGraph(scope, options.context, options.namespaceId, options.modelName, options.data));
|
|
4055
4058
|
}
|
|
4056
4059
|
async function executeNestedUpdateMutation(options) {
|
|
4057
|
-
return withMutationScope(options.runtime, async (scope) => updateFirstGraph(scope, options.context, options.namespaceId, options.modelName, options.filters, options.data));
|
|
4060
|
+
return withMutationScope(options.runtime, async (scope) => updateFirstGraph(scope, options.context, options.namespaceId, options.modelName, options.tables, options.filters, options.data));
|
|
4058
4061
|
}
|
|
4059
4062
|
function buildRowIdentityFilterFromRow(contract, namespaceId, modelName, row) {
|
|
4060
4063
|
const tableName = resolveModelTableName(contract, namespaceId, modelName);
|
|
@@ -4125,9 +4128,9 @@ async function createGraph(scope, context, namespaceId, modelName, input) {
|
|
|
4125
4128
|
for (const relationMutation of junctionOwned) await applyJunctionOwnedMutation(scope, context, namespaceId, modelName, parentRow, relationMutation.relation, relationMutation.mutation);
|
|
4126
4129
|
return parentRow;
|
|
4127
4130
|
}
|
|
4128
|
-
async function updateFirstGraph(scope, context, namespaceId, modelName, filters, input) {
|
|
4131
|
+
async function updateFirstGraph(scope, context, namespaceId, modelName, tables, filters, input) {
|
|
4129
4132
|
const contract = context.contract;
|
|
4130
|
-
const existingRow = await findFirstByFilters(scope, contract, namespaceId, modelName, filters);
|
|
4133
|
+
const existingRow = await findFirstByFilters(scope, contract, namespaceId, modelName, tables, filters);
|
|
4131
4134
|
if (!existingRow) return null;
|
|
4132
4135
|
const parsed = parseMutationInput(contract, namespaceId, modelName, input);
|
|
4133
4136
|
const { parentOwned, childOwned, junctionOwned } = partitionByOwnership(parsed.relationMutations);
|
|
@@ -4145,9 +4148,9 @@ async function updateFirstGraph(scope, context, namespaceId, modelName, filters,
|
|
|
4145
4148
|
values: mappedUpdateData
|
|
4146
4149
|
});
|
|
4147
4150
|
for (const def of appliedUpdateDefaults) mappedUpdateData[def.field] = def.value;
|
|
4148
|
-
const identityWhere = shorthandToWhereExpr(context, namespaceId, modelName, castAs(buildRowIdentityFilterFromRow(contract, namespaceId, modelName, existingRow)));
|
|
4151
|
+
const identityWhere = shorthandToWhereExpr(context, namespaceId, modelName, castAs(buildRowIdentityFilterFromRow(contract, namespaceId, modelName, existingRow)), tables.root);
|
|
4149
4152
|
if (!identityWhere) throw new InternalError(`Failed to build row identity filter for model "${modelName}"`);
|
|
4150
|
-
const updatedRaw = (await queryPlanRows(scope, compileUpdateReturning(contract,
|
|
4153
|
+
const updatedRaw = (await queryPlanRows(scope, compileUpdateReturning(contract, modelName, tables, mappedUpdateData, [identityWhere], void 0)).toArray())[0];
|
|
4151
4154
|
if (updatedRaw) parentRow = mapStorageRowToModelFields(contract, namespaceId, modelName, updatedRaw);
|
|
4152
4155
|
}
|
|
4153
4156
|
for (const relationMutation of childOwned) await applyChildOwnedMutation(scope, context, namespaceId, modelName, parentRow, relationMutation.relation, relationMutation.mutation);
|
|
@@ -4266,7 +4269,8 @@ async function applyChildOwnedMutation(scope, context, parentNamespaceId, parent
|
|
|
4266
4269
|
}
|
|
4267
4270
|
if (mutation.kind === "connect") {
|
|
4268
4271
|
for (const criterion of mutation.criteria) {
|
|
4269
|
-
const
|
|
4272
|
+
const related = createRelatedTables(relation);
|
|
4273
|
+
const criterionWhere = shorthandToWhereExpr(context, relation.relatedNamespaceId, relation.relatedModelName, castAs(criterion), related.root);
|
|
4270
4274
|
if (!criterionWhere) throw ormError("ORM.RELATION_MUTATION_INVALID", `connect() nested mutation for relation "${relation.relationName}" requires non-empty criterion`, { meta: {
|
|
4271
4275
|
kind: "connect",
|
|
4272
4276
|
relation: relation.relationName,
|
|
@@ -4274,26 +4278,26 @@ async function applyChildOwnedMutation(scope, context, parentNamespaceId, parent
|
|
|
4274
4278
|
} });
|
|
4275
4279
|
const setValues = {};
|
|
4276
4280
|
for (const [childColumn, parentValue] of parentValues.entries()) setValues[childColumn] = parentValue;
|
|
4277
|
-
await executeUpdateCount(scope, contract,
|
|
4281
|
+
await executeUpdateCount(scope, contract, related, setValues, [criterionWhere]);
|
|
4278
4282
|
}
|
|
4279
4283
|
return;
|
|
4280
4284
|
}
|
|
4281
4285
|
const setValues = {};
|
|
4282
4286
|
for (const childColumn of parentValues.keys()) setValues[childColumn] = null;
|
|
4283
4287
|
if (!mutation.criteria || mutation.criteria.length === 0) {
|
|
4284
|
-
const
|
|
4285
|
-
await executeUpdateCount(scope, contract,
|
|
4288
|
+
const related = createRelatedTables(relation);
|
|
4289
|
+
await executeUpdateCount(scope, contract, related, setValues, [buildChildJoinWhere(contract, related.root, parentValues)]);
|
|
4286
4290
|
return;
|
|
4287
4291
|
}
|
|
4288
4292
|
for (const criterion of mutation.criteria) {
|
|
4289
|
-
const
|
|
4293
|
+
const related = createRelatedTables(relation);
|
|
4294
|
+
const criterionWhere = shorthandToWhereExpr(context, relation.relatedNamespaceId, relation.relatedModelName, castAs(criterion), related.root);
|
|
4290
4295
|
if (!criterionWhere) throw ormError("ORM.RELATION_MUTATION_INVALID", `disconnect() nested mutation for relation "${relation.relationName}" requires non-empty criterion`, { meta: {
|
|
4291
4296
|
kind: "disconnect",
|
|
4292
4297
|
relation: relation.relationName,
|
|
4293
4298
|
problem: "empty-criterion"
|
|
4294
4299
|
} });
|
|
4295
|
-
|
|
4296
|
-
await executeUpdateCount(scope, contract, relation.relatedNamespaceId, relation.relatedTableName, setValues, [and(parentJoinWhere, criterionWhere)]);
|
|
4300
|
+
await executeUpdateCount(scope, contract, related, setValues, [and(buildChildJoinWhere(contract, related.root, parentValues), criterionWhere)]);
|
|
4297
4301
|
}
|
|
4298
4302
|
}
|
|
4299
4303
|
async function applyJunctionOwnedMutation(scope, context, parentNamespaceId, parentModelName, parentRow, relation, mutation) {
|
|
@@ -4432,11 +4436,15 @@ async function deleteJunctionLink(scope, context, relation, parentPkValues, targ
|
|
|
4432
4436
|
const junctionRow = {};
|
|
4433
4437
|
for (const [column, value] of parentPkValues.entries()) writeJunctionColumn(junctionRow, through, column, value, relation.relationName);
|
|
4434
4438
|
for (const [column, value] of targetPkValues.entries()) writeJunctionColumn(junctionRow, through, column, value, relation.relationName);
|
|
4439
|
+
const junction = createStatementTables({
|
|
4440
|
+
namespaceId: through.namespaceId,
|
|
4441
|
+
tableName: through.table
|
|
4442
|
+
});
|
|
4435
4443
|
const exprs = [];
|
|
4436
|
-
for (const [column, value] of Object.entries(junctionRow)) exprs.push(BinaryExpr.eq(
|
|
4444
|
+
for (const [column, value] of Object.entries(junctionRow)) exprs.push(BinaryExpr.eq(junction.root.column(column), paramRefForStorageColumn(context.contract, junction.root.storage, column, value)));
|
|
4437
4445
|
const first = exprs[0];
|
|
4438
4446
|
const where = exprs.length === 1 && first !== void 0 ? first : and(...exprs);
|
|
4439
|
-
const compiled = compileDeleteCount(context.contract,
|
|
4447
|
+
const compiled = compileDeleteCount(context.contract, junction, [where]);
|
|
4440
4448
|
await scope.execute(compiled);
|
|
4441
4449
|
}
|
|
4442
4450
|
function readParentColumnValues(contract, parentNamespaceId, parentModelName, relation, parentRow) {
|
|
@@ -4452,9 +4460,15 @@ function readParentColumnValues(contract, parentNamespaceId, parentModelName, re
|
|
|
4452
4460
|
}
|
|
4453
4461
|
return values;
|
|
4454
4462
|
}
|
|
4455
|
-
function
|
|
4463
|
+
function createRelatedTables(relation) {
|
|
4464
|
+
return createStatementTables({
|
|
4465
|
+
namespaceId: relation.relatedNamespaceId,
|
|
4466
|
+
tableName: relation.relatedTableName
|
|
4467
|
+
});
|
|
4468
|
+
}
|
|
4469
|
+
function buildChildJoinWhere(contract, related, childValues) {
|
|
4456
4470
|
const exprs = [];
|
|
4457
|
-
for (const [childColumn, parentValue] of childValues.entries()) exprs.push(BinaryExpr.eq(
|
|
4471
|
+
for (const [childColumn, parentValue] of childValues.entries()) exprs.push(BinaryExpr.eq(related.column(childColumn), paramRefForStorageColumn(contract, related.storage, childColumn, parentValue)));
|
|
4458
4472
|
const first = exprs[0];
|
|
4459
4473
|
if (exprs.length === 1 && first !== void 0) return first;
|
|
4460
4474
|
return and(...exprs);
|
|
@@ -4480,31 +4494,35 @@ async function insertSingleRow(scope, context, namespaceId, modelName, data) {
|
|
|
4480
4494
|
}
|
|
4481
4495
|
async function findRowByCriterion(scope, context, namespaceId, modelName, criterion) {
|
|
4482
4496
|
const contract = context.contract;
|
|
4483
|
-
const
|
|
4497
|
+
const tables = createStatementTables({
|
|
4498
|
+
namespaceId,
|
|
4499
|
+
tableName: resolveModelTableName(contract, namespaceId, modelName)
|
|
4500
|
+
});
|
|
4501
|
+
const whereExpr = shorthandToWhereExpr(context, namespaceId, modelName, castAs(criterion), tables.root);
|
|
4484
4502
|
if (!whereExpr) throw ormError("ORM.RELATION_MUTATION_INVALID", `Nested connect for model "${modelName}" requires non-empty criterion`, { meta: {
|
|
4485
4503
|
kind: "connect",
|
|
4486
4504
|
model: modelName,
|
|
4487
4505
|
problem: "empty-criterion"
|
|
4488
4506
|
} });
|
|
4489
|
-
const firstRow = (await queryPlanRows(scope, compileSelect(contract,
|
|
4490
|
-
...emptyState(),
|
|
4507
|
+
const firstRow = (await queryPlanRows(scope, compileSelect(contract, modelName, {
|
|
4508
|
+
...emptyState(tables),
|
|
4491
4509
|
filters: [whereExpr],
|
|
4492
4510
|
limit: 1
|
|
4493
4511
|
})).toArray())[0];
|
|
4494
4512
|
if (!firstRow) return null;
|
|
4495
4513
|
return mapStorageRowToModelFields(contract, namespaceId, modelName, firstRow);
|
|
4496
4514
|
}
|
|
4497
|
-
async function findFirstByFilters(scope, contract, namespaceId, modelName, filters) {
|
|
4498
|
-
const firstRow = (await queryPlanRows(scope, compileSelect(contract,
|
|
4499
|
-
...emptyState(),
|
|
4515
|
+
async function findFirstByFilters(scope, contract, namespaceId, modelName, tables, filters) {
|
|
4516
|
+
const firstRow = (await queryPlanRows(scope, compileSelect(contract, modelName, {
|
|
4517
|
+
...emptyState(tables),
|
|
4500
4518
|
filters,
|
|
4501
4519
|
limit: 1
|
|
4502
4520
|
})).toArray())[0];
|
|
4503
4521
|
if (!firstRow) return null;
|
|
4504
4522
|
return mapStorageRowToModelFields(contract, namespaceId, modelName, firstRow);
|
|
4505
4523
|
}
|
|
4506
|
-
async function executeUpdateCount(scope, contract,
|
|
4507
|
-
const compiled = compileUpdateCount(contract,
|
|
4524
|
+
async function executeUpdateCount(scope, contract, tables, setValues, filters) {
|
|
4525
|
+
const compiled = compileUpdateCount(contract, tables, setValues, filters);
|
|
4508
4526
|
await scope.execute(compiled);
|
|
4509
4527
|
}
|
|
4510
4528
|
const relationDefsCache = /* @__PURE__ */ new WeakMap();
|
|
@@ -4544,9 +4562,9 @@ function toFieldName(contract, namespaceId, modelName, columnName) {
|
|
|
4544
4562
|
function normalizeWhereArg(arg, options) {
|
|
4545
4563
|
if (arg === void 0) return;
|
|
4546
4564
|
if (arg === null) throw ormError("ORM.ARGUMENT_INVALID", "WhereArg cannot be null. Pass undefined or a valid WhereExpr/ToWhereExpr payload.", { meta: { argument: "where" } });
|
|
4547
|
-
|
|
4548
|
-
if (options
|
|
4549
|
-
return
|
|
4565
|
+
const expr = isToWhereExpr(arg) ? arg.toWhereExpr() : arg;
|
|
4566
|
+
if (!options) return expr;
|
|
4567
|
+
return bindWhereExpr(options.contract, expr, options.tables);
|
|
4550
4568
|
}
|
|
4551
4569
|
function isToWhereExpr(arg) {
|
|
4552
4570
|
return typeof arg === "object" && arg !== null && "toWhereExpr" in arg && !isWhereExpr(arg);
|
|
@@ -4707,7 +4725,7 @@ var CollectionBase = class CollectionBase {
|
|
|
4707
4725
|
this.modelName = modelName;
|
|
4708
4726
|
this.namespaceId = options.namespaceId;
|
|
4709
4727
|
this.tableName = options.tableName ?? resolveModelTableName(this.contract, options.namespaceId, modelName);
|
|
4710
|
-
this.state = options.state ?? emptyState();
|
|
4728
|
+
this.state = options.state ?? emptyState(createCollectionTables(this.contract, options.namespaceId, modelName, this.tableName));
|
|
4711
4729
|
this.registry = options.registry ?? /* @__PURE__ */ new Map();
|
|
4712
4730
|
this.includeRefinementMode = options.includeRefinementMode ?? false;
|
|
4713
4731
|
this.#installAggregateReducers();
|
|
@@ -4755,15 +4773,19 @@ var CollectionBase = class CollectionBase {
|
|
|
4755
4773
|
return createIncludeScalar(operation, this.state, column);
|
|
4756
4774
|
}
|
|
4757
4775
|
where(input) {
|
|
4758
|
-
const
|
|
4776
|
+
const tables = withScopeCopy(this.state.tables);
|
|
4777
|
+
const filter = normalizeWhereArg(typeof input === "function" ? whereArgOf(input(createModelAccessor(this.ctx.context, this.namespaceId, this.modelName, tables, this.state.variantName), this.#callbackTools(tables))) : isWhereDirectInput(input) ? input : shorthandToWhereExpr(this.ctx.context, this.namespaceId, this.modelName, input, tables.root), {
|
|
4759
4778
|
contract: this.contract,
|
|
4760
|
-
|
|
4779
|
+
tables: tableAliases(tables)
|
|
4761
4780
|
});
|
|
4762
4781
|
if (!filter) return blindCast(this);
|
|
4763
|
-
return this.#cloneSelf({
|
|
4782
|
+
return this.#cloneSelf({
|
|
4783
|
+
tables,
|
|
4784
|
+
filters: [...this.state.filters, filter]
|
|
4785
|
+
});
|
|
4764
4786
|
}
|
|
4765
|
-
#callbackTools() {
|
|
4766
|
-
return createModelCallbackTools(this.ctx.context, this.
|
|
4787
|
+
#callbackTools(tables) {
|
|
4788
|
+
return createModelCallbackTools(this.ctx.context, this.modelName, tables);
|
|
4767
4789
|
}
|
|
4768
4790
|
with(fn) {
|
|
4769
4791
|
return fn(this);
|
|
@@ -4815,7 +4837,7 @@ var CollectionBase = class CollectionBase {
|
|
|
4815
4837
|
} });
|
|
4816
4838
|
}
|
|
4817
4839
|
const columnName = polyInfo.discriminatorColumn;
|
|
4818
|
-
const filter = BinaryExpr.eq(
|
|
4840
|
+
const filter = BinaryExpr.eq(this.state.tables.root.column(columnName), paramRefForStorageColumn(this.contract, this.state.tables.root.storage, columnName, variantInfo.value));
|
|
4819
4841
|
return this.#cloneWithRow({
|
|
4820
4842
|
filters: [...this.state.filters, filter],
|
|
4821
4843
|
variantName: variantInfo.modelName
|
|
@@ -4823,14 +4845,16 @@ var CollectionBase = class CollectionBase {
|
|
|
4823
4845
|
}
|
|
4824
4846
|
include(relationName, refineFn) {
|
|
4825
4847
|
const relation = resolveIncludeRelation(this.contract, this.namespaceId, this.modelName, relationName, this.state.variantName);
|
|
4826
|
-
|
|
4848
|
+
const child = createIncludeTables(this.contract, this.state.tables, relation);
|
|
4849
|
+
let nestedState = emptyState(child.tables);
|
|
4850
|
+
let adoptedScope = child.tables.scope;
|
|
4827
4851
|
let scalarSelector;
|
|
4828
4852
|
let combineBranches;
|
|
4829
4853
|
if (refineFn) {
|
|
4830
4854
|
const refined = refineFn(this.#createCollection(blindCast(relation.relatedModelName), {
|
|
4831
4855
|
tableName: relation.relatedTableName,
|
|
4832
4856
|
namespaceId: relation.relatedNamespaceId,
|
|
4833
|
-
state:
|
|
4857
|
+
state: nestedState,
|
|
4834
4858
|
includeRefinementMode: true
|
|
4835
4859
|
}));
|
|
4836
4860
|
if (isIncludeScalar(refined)) {
|
|
@@ -4838,6 +4862,7 @@ var CollectionBase = class CollectionBase {
|
|
|
4838
4862
|
relation: relationName,
|
|
4839
4863
|
kind: "scalar"
|
|
4840
4864
|
} });
|
|
4865
|
+
adoptedScope = refined.state.tables.scope;
|
|
4841
4866
|
scalarSelector = refined;
|
|
4842
4867
|
nestedState = refined.state;
|
|
4843
4868
|
} else if (isIncludeCombine(refined)) {
|
|
@@ -4846,35 +4871,48 @@ var CollectionBase = class CollectionBase {
|
|
|
4846
4871
|
kind: "combine"
|
|
4847
4872
|
} });
|
|
4848
4873
|
combineBranches = refined.branches;
|
|
4849
|
-
} else if (isCollectionStateCarrier(refined))
|
|
4850
|
-
|
|
4874
|
+
} else if (isCollectionStateCarrier(refined)) {
|
|
4875
|
+
adoptedScope = refined.state.tables.scope;
|
|
4876
|
+
nestedState = refined.state;
|
|
4877
|
+
} else throw ormError("ORM.INCLUDE_INVALID", `include('${relationName}') refinement must return a collection, include scalar selector, or combine() descriptor`, { meta: { relation: relationName } });
|
|
4851
4878
|
}
|
|
4852
4879
|
const includeExpr = {
|
|
4853
4880
|
relationName,
|
|
4854
4881
|
relatedModelName: relation.relatedModelName,
|
|
4855
4882
|
relatedNamespaceId: relation.relatedNamespaceId,
|
|
4856
4883
|
relatedTableName: relation.relatedTableName,
|
|
4857
|
-
|
|
4884
|
+
...ifDefined("localVariantName", relation.localVariantName),
|
|
4858
4885
|
targetColumns: relation.targetColumns,
|
|
4859
4886
|
localColumns: relation.localColumns,
|
|
4860
4887
|
cardinality: relation.cardinality,
|
|
4861
4888
|
...ifDefined("through", relation.through),
|
|
4889
|
+
...ifDefined("junction", child.junction),
|
|
4862
4890
|
nested: nestedState,
|
|
4863
4891
|
scalar: scalarSelector,
|
|
4864
4892
|
combine: combineBranches
|
|
4865
4893
|
};
|
|
4866
|
-
return this.#cloneWithRow({
|
|
4894
|
+
return this.#cloneWithRow({
|
|
4895
|
+
tables: {
|
|
4896
|
+
...this.state.tables,
|
|
4897
|
+
scope: adoptedScope
|
|
4898
|
+
},
|
|
4899
|
+
includes: [...this.state.includes, includeExpr]
|
|
4900
|
+
});
|
|
4867
4901
|
}
|
|
4868
4902
|
select(...fields) {
|
|
4869
4903
|
const selectedFields = mapSelectedFieldsToColumns(this.contract, this.namespaceId, this.modelName, this.state.variantName, fields);
|
|
4870
4904
|
return this.#cloneWithRow({ selectedFields });
|
|
4871
4905
|
}
|
|
4872
4906
|
orderBy(selection) {
|
|
4873
|
-
const
|
|
4874
|
-
const
|
|
4907
|
+
const tables = withScopeCopy(this.state.tables);
|
|
4908
|
+
const accessor = createModelAccessor(this.ctx.context, this.namespaceId, this.modelName, tables, this.state.variantName);
|
|
4909
|
+
const tools = this.#callbackTools(tables);
|
|
4875
4910
|
const nextOrders = (Array.isArray(selection) ? selection : [selection]).map((selector) => selector(accessor, tools));
|
|
4876
4911
|
const existing = this.state.orderBy ?? [];
|
|
4877
|
-
return this.#cloneSelf({
|
|
4912
|
+
return this.#cloneSelf({
|
|
4913
|
+
tables,
|
|
4914
|
+
orderBy: [...existing, ...nextOrders]
|
|
4915
|
+
});
|
|
4878
4916
|
}
|
|
4879
4917
|
/**
|
|
4880
4918
|
* Switch to grouped-aggregate mode. Returns a `GroupedCollection`
|
|
@@ -5006,7 +5044,6 @@ var CollectionBase = class CollectionBase {
|
|
|
5006
5044
|
return {
|
|
5007
5045
|
context: this.ctx.context,
|
|
5008
5046
|
state: this.state,
|
|
5009
|
-
tableName: this.tableName,
|
|
5010
5047
|
modelName: this.modelName,
|
|
5011
5048
|
namespaceId: this.namespaceId
|
|
5012
5049
|
};
|
|
@@ -5059,7 +5096,7 @@ var CollectionBase = class CollectionBase {
|
|
|
5059
5096
|
alias
|
|
5060
5097
|
} });
|
|
5061
5098
|
const annotationsMap = this.#collectAnnotationsFromMeta(configure, "read", "aggregate");
|
|
5062
|
-
const compiled = mergeAnnotations(compileAggregate(this.contract, this.ctx.context.aggregateDescriptors, this.
|
|
5099
|
+
const compiled = mergeAnnotations(compileAggregate(this.contract, this.ctx.context.aggregateDescriptors, this.state, aggregateSpec, this.modelName), annotationsMap);
|
|
5063
5100
|
const results = entries.map(([alias, selector]) => {
|
|
5064
5101
|
const resolved = resolveAggregate({
|
|
5065
5102
|
aggregates: this.ctx.context.aggregateDescriptors,
|
|
@@ -5136,7 +5173,7 @@ var CollectionBase = class CollectionBase {
|
|
|
5136
5173
|
context: this.ctx.context,
|
|
5137
5174
|
runtime: this.ctx.runtime,
|
|
5138
5175
|
plans,
|
|
5139
|
-
|
|
5176
|
+
tables: this.state.tables,
|
|
5140
5177
|
modelName: this.modelName,
|
|
5141
5178
|
namespaceId: this.namespaceId,
|
|
5142
5179
|
variantName: this.state.variantName,
|
|
@@ -5151,7 +5188,7 @@ var CollectionBase = class CollectionBase {
|
|
|
5151
5188
|
context: this.ctx.context,
|
|
5152
5189
|
runtime: this.ctx.runtime,
|
|
5153
5190
|
compiled,
|
|
5154
|
-
|
|
5191
|
+
tables: this.state.tables,
|
|
5155
5192
|
modelName: this.modelName,
|
|
5156
5193
|
namespaceId: this.namespaceId,
|
|
5157
5194
|
variantName: this.state.variantName,
|
|
@@ -5215,6 +5252,8 @@ var CollectionBase = class CollectionBase {
|
|
|
5215
5252
|
const tableName = this.tableName;
|
|
5216
5253
|
const modelName = this.modelName;
|
|
5217
5254
|
const namespaceId = this.namespaceId;
|
|
5255
|
+
const tables = this.state.tables;
|
|
5256
|
+
const variantTable = requireVariantTable(tables, variant.modelName);
|
|
5218
5257
|
const baseFieldColumns = new Set(Object.values(baseFieldToColumn));
|
|
5219
5258
|
const variantFieldColumns = new Set(Object.values(variantFieldToColumn));
|
|
5220
5259
|
const generator = async function* () {
|
|
@@ -5242,8 +5281,8 @@ var CollectionBase = class CollectionBase {
|
|
|
5242
5281
|
phase: "mti-base"
|
|
5243
5282
|
} });
|
|
5244
5283
|
for (const pkColumn of pkColumns) variantRow[pkColumn] = baseCreated[pkColumn];
|
|
5245
|
-
applyCreateDefaults(collectionCtx, namespaceId,
|
|
5246
|
-
const variantCreated = (await queryPlanRows(scope, compileInsertReturning(contract, namespaceId, variant.modelName,
|
|
5284
|
+
applyCreateDefaults(collectionCtx, variantTable.storage.namespaceId, variantTable.storage.tableName, [variantRow], defaultValueCache);
|
|
5285
|
+
const variantCreated = (await queryPlanRows(scope, compileInsertReturning(contract, variantTable.storage.namespaceId, variant.modelName, variantTable.storage.tableName, [variantRow], void 0)).toArray())[0];
|
|
5247
5286
|
if (!variantCreated) throw ormError("ORM.MUTATION_ROW_MISSING", `MTI variant INSERT for model "${modelName}" into "${variant.table}" did not return a row`, { meta: {
|
|
5248
5287
|
operation: "create",
|
|
5249
5288
|
model: modelName,
|
|
@@ -5253,9 +5292,9 @@ var CollectionBase = class CollectionBase {
|
|
|
5253
5292
|
const prefixedVariant = {};
|
|
5254
5293
|
for (const [col, val] of Object.entries(variantCreated)) {
|
|
5255
5294
|
if (pkColumns.includes(col)) continue;
|
|
5256
|
-
prefixedVariant[
|
|
5295
|
+
prefixedVariant[variantColumnLabel(variantTable, col)] = val;
|
|
5257
5296
|
}
|
|
5258
|
-
return mapPolymorphicRow(contract, namespaceId, modelName, polyInfo, {
|
|
5297
|
+
return mapPolymorphicRow(contract, namespaceId, modelName, polyInfo, tables, {
|
|
5259
5298
|
...baseCreated,
|
|
5260
5299
|
...prefixedVariant
|
|
5261
5300
|
}, variant.modelName);
|
|
@@ -5350,7 +5389,7 @@ var CollectionBase = class CollectionBase {
|
|
|
5350
5389
|
context: this.ctx.context,
|
|
5351
5390
|
runtime: this.ctx.runtime,
|
|
5352
5391
|
compiled,
|
|
5353
|
-
|
|
5392
|
+
tables: this.state.tables,
|
|
5354
5393
|
modelName: this.modelName,
|
|
5355
5394
|
namespaceId: this.namespaceId,
|
|
5356
5395
|
variantName: this.state.variantName,
|
|
@@ -5383,6 +5422,7 @@ var CollectionBase = class CollectionBase {
|
|
|
5383
5422
|
runtime: this.ctx.runtime,
|
|
5384
5423
|
namespaceId: this.namespaceId,
|
|
5385
5424
|
modelName: this.modelName,
|
|
5425
|
+
tables: this.state.tables,
|
|
5386
5426
|
filters: this.state.filters,
|
|
5387
5427
|
data: blindCast(data)
|
|
5388
5428
|
});
|
|
@@ -5412,12 +5452,12 @@ var CollectionBase = class CollectionBase {
|
|
|
5412
5452
|
}
|
|
5413
5453
|
applyUpdateDefaults(this.ctx, this.namespaceId, this.tableName, mappedData);
|
|
5414
5454
|
const { selectedForQuery: selectedForUpdate, hiddenColumns } = this.#augmentMutationSelection();
|
|
5415
|
-
const compiled = mergeAnnotations(compileUpdateReturning(this.contract, this.
|
|
5455
|
+
const compiled = mergeAnnotations(compileUpdateReturning(this.contract, this.modelName, this.state.tables, mappedData, this.state.filters, selectedForUpdate), annotationsMap);
|
|
5416
5456
|
return dispatchMutationRows({
|
|
5417
5457
|
context: this.ctx.context,
|
|
5418
5458
|
runtime: this.ctx.runtime,
|
|
5419
5459
|
compiled,
|
|
5420
|
-
|
|
5460
|
+
tables: this.state.tables,
|
|
5421
5461
|
modelName: this.modelName,
|
|
5422
5462
|
namespaceId: this.namespaceId,
|
|
5423
5463
|
variantName: this.state.variantName,
|
|
@@ -5434,7 +5474,7 @@ var CollectionBase = class CollectionBase {
|
|
|
5434
5474
|
if (Object.keys(mappedData).length === 0) return 0;
|
|
5435
5475
|
applyUpdateDefaults(this.ctx, this.namespaceId, this.tableName, mappedData);
|
|
5436
5476
|
const annotationsMap = this.#collectAnnotationsFromMeta(configure, "write", "updateAndCount");
|
|
5437
|
-
const compiled = mergeAnnotations(compileUpdateCount(this.contract, this.
|
|
5477
|
+
const compiled = mergeAnnotations(compileUpdateCount(this.contract, this.state.tables, mappedData, this.state.filters, this.state.variantName), annotationsMap);
|
|
5438
5478
|
return (await this.ctx.runtime.execute(compiled)).affectedRows;
|
|
5439
5479
|
}
|
|
5440
5480
|
async delete(configure) {
|
|
@@ -5464,12 +5504,12 @@ var CollectionBase = class CollectionBase {
|
|
|
5464
5504
|
#executeDeleteReturning(annotationsMap) {
|
|
5465
5505
|
if (this.state.includes.length > 0) return this.#executeDeleteReturningWithIncludes(annotationsMap);
|
|
5466
5506
|
const { selectedForQuery: selectedForDelete, hiddenColumns } = this.#augmentMutationSelection();
|
|
5467
|
-
const compiled = mergeAnnotations(compileDeleteReturning(this.contract, this.
|
|
5507
|
+
const compiled = mergeAnnotations(compileDeleteReturning(this.contract, this.modelName, this.state.tables, this.state.filters, selectedForDelete), annotationsMap);
|
|
5468
5508
|
return dispatchMutationRows({
|
|
5469
5509
|
context: this.ctx.context,
|
|
5470
5510
|
runtime: this.ctx.runtime,
|
|
5471
5511
|
compiled,
|
|
5472
|
-
|
|
5512
|
+
tables: this.state.tables,
|
|
5473
5513
|
modelName: this.modelName,
|
|
5474
5514
|
namespaceId: this.namespaceId,
|
|
5475
5515
|
variantName: this.state.variantName,
|
|
@@ -5500,11 +5540,10 @@ var CollectionBase = class CollectionBase {
|
|
|
5500
5540
|
context: collection.ctx.context,
|
|
5501
5541
|
runtime: scope,
|
|
5502
5542
|
state: collection.state,
|
|
5503
|
-
tableName: collection.tableName,
|
|
5504
5543
|
modelName: collection.modelName,
|
|
5505
5544
|
namespaceId: collection.namespaceId
|
|
5506
5545
|
}).toArray();
|
|
5507
|
-
const deletePlan = mergeAnnotations(compileDeleteCount(collection.contract, collection.
|
|
5546
|
+
const deletePlan = mergeAnnotations(compileDeleteCount(collection.contract, collection.state.tables, collection.state.filters, collection.state.variantName), annotationsMap);
|
|
5508
5547
|
await scope.execute(deletePlan);
|
|
5509
5548
|
return rows;
|
|
5510
5549
|
});
|
|
@@ -5516,7 +5555,7 @@ var CollectionBase = class CollectionBase {
|
|
|
5516
5555
|
assertBulkWriteIgnoresNothing(this.state, this.modelName, "deleteAndCount");
|
|
5517
5556
|
assertLockCompatible(this.state, "mutation");
|
|
5518
5557
|
const annotationsMap = this.#collectAnnotationsFromMeta(configure, "write", "deleteAndCount");
|
|
5519
|
-
const compiled = mergeAnnotations(compileDeleteCount(this.contract, this.
|
|
5558
|
+
const compiled = mergeAnnotations(compileDeleteCount(this.contract, this.state.tables, this.state.filters, this.state.variantName), annotationsMap);
|
|
5520
5559
|
return (await this.ctx.runtime.execute(compiled)).affectedRows;
|
|
5521
5560
|
}
|
|
5522
5561
|
#buildUpsertConflictCriterion(createValues, conflictColumns) {
|
|
@@ -5579,16 +5618,16 @@ var CollectionBase = class CollectionBase {
|
|
|
5579
5618
|
if (value === void 0) throw new InternalError(`Missing identity field "${fieldName}" while resolving single-row scope for model "${this.modelName}"`);
|
|
5580
5619
|
criterion[fieldName] = value;
|
|
5581
5620
|
}
|
|
5582
|
-
return shorthandToWhereExpr(this.ctx.context, this.namespaceId, this.modelName, blindCast(criterion)) ?? null;
|
|
5621
|
+
return shorthandToWhereExpr(this.ctx.context, this.namespaceId, this.modelName, blindCast(criterion), this.state.tables.root) ?? null;
|
|
5583
5622
|
}
|
|
5584
5623
|
async #reloadMutationRowByIdentity(criterion) {
|
|
5585
5624
|
return this.#reloadMutationRowByCriterion(criterion, "row identity");
|
|
5586
5625
|
}
|
|
5587
5626
|
async #reloadMutationRowByCriterion(criterion, criterionLabel) {
|
|
5588
|
-
const whereExpr = shorthandToWhereExpr(this.ctx.context, this.namespaceId, this.modelName, blindCast(criterion));
|
|
5627
|
+
const whereExpr = shorthandToWhereExpr(this.ctx.context, this.namespaceId, this.modelName, blindCast(criterion), this.state.tables.root);
|
|
5589
5628
|
if (!whereExpr) throw new InternalError(`Failed to build ${criterionLabel} filter for mutation result on model "${this.modelName}"`);
|
|
5590
5629
|
const resultState = {
|
|
5591
|
-
...emptyState(),
|
|
5630
|
+
...emptyState(this.state.tables),
|
|
5592
5631
|
filters: [whereExpr],
|
|
5593
5632
|
includes: this.state.includes,
|
|
5594
5633
|
selectedFields: this.state.selectedFields,
|
|
@@ -5598,7 +5637,6 @@ var CollectionBase = class CollectionBase {
|
|
|
5598
5637
|
context: this.ctx.context,
|
|
5599
5638
|
runtime: this.ctx.runtime,
|
|
5600
5639
|
state: resultState,
|
|
5601
|
-
tableName: this.tableName,
|
|
5602
5640
|
modelName: this.modelName,
|
|
5603
5641
|
namespaceId: this.namespaceId
|
|
5604
5642
|
}))[0] ?? null;
|
|
@@ -5614,7 +5652,7 @@ var CollectionBase = class CollectionBase {
|
|
|
5614
5652
|
const waitPolicy = lockWaitPolicyOf(strength, options);
|
|
5615
5653
|
if (waitPolicy !== void 0) assertLockCapability(this.contract, lockOptionCapabilities[waitPolicy], strength);
|
|
5616
5654
|
const clause = LockingClause.of(strength, {
|
|
5617
|
-
of: [this.
|
|
5655
|
+
of: [this.state.tables.root.alias],
|
|
5618
5656
|
...ifDefined("waitPolicy", waitPolicy)
|
|
5619
5657
|
});
|
|
5620
5658
|
return this.#cloneSelf({ locking: [...this.state.locking ?? [], clause] });
|
|
@@ -5672,7 +5710,6 @@ var CollectionBase = class CollectionBase {
|
|
|
5672
5710
|
context: this.ctx.context,
|
|
5673
5711
|
runtime: this.ctx.runtime,
|
|
5674
5712
|
state: this.state,
|
|
5675
|
-
tableName: this.tableName,
|
|
5676
5713
|
modelName: this.modelName,
|
|
5677
5714
|
namespaceId: this.namespaceId
|
|
5678
5715
|
});
|
|
@@ -5839,6 +5876,6 @@ function createPreparedRowQuery(description, statement) {
|
|
|
5839
5876
|
} });
|
|
5840
5877
|
}
|
|
5841
5878
|
//#endregion
|
|
5842
|
-
export { Collection, GroupedCollection, all, and, createModelAccessor, createPreparedRowQuery, emptyState, not, or, orderByField, orm, prepareQuery };
|
|
5879
|
+
export { Collection, GroupedCollection, all, and, createCollectionTables, createModelAccessor, createPreparedRowQuery, emptyState, not, or, orderByField, orm, prepareQuery };
|
|
5843
5880
|
|
|
5844
5881
|
//# sourceMappingURL=orm-client.mjs.map
|