@nshiab/simple-data-analysis-core 2.1.7 → 2.1.9
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/esm/class/SimpleTable.d.ts +191 -108
- package/esm/class/SimpleTable.d.ts.map +1 -1
- package/esm/class/SimpleTable.js +188 -105
- package/esm/helpers/buildGraphTemporalCostStateSql.d.ts +1 -1
- package/esm/helpers/buildGraphTemporalCostStateSql.d.ts.map +1 -1
- package/esm/helpers/buildGraphTemporalCostStateSql.js +23 -9
- package/esm/helpers/graphRouteResultSchema.d.ts +1 -1
- package/esm/helpers/graphRouteResultSchema.d.ts.map +1 -1
- package/esm/helpers/graphRouteResultSchema.js +3 -3
- package/esm/helpers/graphRouteResultSelect.d.ts +1 -1
- package/esm/helpers/graphRouteResultSelect.d.ts.map +1 -1
- package/esm/helpers/graphRouteResultSelect.js +2 -2
- package/esm/helpers/prepareGraphMetricOptions.d.ts +2 -2
- package/esm/helpers/prepareGraphMetricOptions.d.ts.map +1 -1
- package/esm/helpers/prepareGraphMetricOptions.js +5 -4
- package/esm/helpers/prepareGraphRouteSql.d.ts +2 -2
- package/esm/helpers/prepareGraphRouteSql.d.ts.map +1 -1
- package/esm/helpers/prepareGraphRouteSql.js +4 -4
- package/esm/helpers/validateGraphRouteResultSchema.d.ts +1 -1
- package/esm/helpers/validateGraphRouteResultSchema.d.ts.map +1 -1
- package/esm/helpers/validateGraphRouteResultSchema.js +3 -1
- package/esm/methods/distances.d.ts +1 -1
- package/esm/methods/distances.d.ts.map +1 -1
- package/esm/methods/distances.js +235 -73
- package/esm/methods/shortestPath.d.ts +1 -1
- package/esm/methods/shortestPath.d.ts.map +1 -1
- package/esm/methods/shortestPath.js +44 -28
- package/esm/methods/similarityMahalanobis.js +3 -3
- package/llm.md +214 -119
- package/llms.txt +1 -1
- package/package.json +1 -1
- package/script/class/SimpleTable.d.ts +191 -108
- package/script/class/SimpleTable.d.ts.map +1 -1
- package/script/class/SimpleTable.js +188 -105
- package/script/helpers/buildGraphTemporalCostStateSql.d.ts +1 -1
- package/script/helpers/buildGraphTemporalCostStateSql.d.ts.map +1 -1
- package/script/helpers/buildGraphTemporalCostStateSql.js +23 -9
- package/script/helpers/graphRouteResultSchema.d.ts +1 -1
- package/script/helpers/graphRouteResultSchema.d.ts.map +1 -1
- package/script/helpers/graphRouteResultSchema.js +3 -3
- package/script/helpers/graphRouteResultSelect.d.ts +1 -1
- package/script/helpers/graphRouteResultSelect.d.ts.map +1 -1
- package/script/helpers/graphRouteResultSelect.js +2 -2
- package/script/helpers/prepareGraphMetricOptions.d.ts +2 -2
- package/script/helpers/prepareGraphMetricOptions.d.ts.map +1 -1
- package/script/helpers/prepareGraphMetricOptions.js +5 -4
- package/script/helpers/prepareGraphRouteSql.d.ts +2 -2
- package/script/helpers/prepareGraphRouteSql.d.ts.map +1 -1
- package/script/helpers/prepareGraphRouteSql.js +4 -4
- package/script/helpers/validateGraphRouteResultSchema.d.ts +1 -1
- package/script/helpers/validateGraphRouteResultSchema.d.ts.map +1 -1
- package/script/helpers/validateGraphRouteResultSchema.js +3 -1
- package/script/methods/distances.d.ts +1 -1
- package/script/methods/distances.d.ts.map +1 -1
- package/script/methods/distances.js +235 -73
- package/script/methods/shortestPath.d.ts +1 -1
- package/script/methods/shortestPath.d.ts.map +1 -1
- package/script/methods/shortestPath.js +44 -28
- package/script/methods/similarityMahalanobis.js +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prepareGraphMetricOptions.d.ts","sourceRoot":"","sources":["../../src/helpers/prepareGraphMetricOptions.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,kBAAkB,GAAG;IAC/B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,EAAE,QAAQ,GAAG,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"prepareGraphMetricOptions.d.ts","sourceRoot":"","sources":["../../src/helpers/prepareGraphMetricOptions.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,kBAAkB,GAAG;IAC/B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,aAAa,CAAC;IAC9C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,0BAA0B,GAAG;IACvC,WAAW,EAAE,OAAO,CAAC;IACrB,QAAQ,EAAE,OAAO,GAAG,QAAQ,GAAG,aAAa,CAAC;CAC9C,CAAC;AAEF,qFAAqF;AACrF,MAAM,CAAC,OAAO,UAAU,yBAAyB,CAC/C,OAAO,EAAE,kBAAkB,EAC3B,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,OAAO,GAChB,0BAA0B,CA2D5B"}
|
|
@@ -14,8 +14,9 @@ export default function prepareGraphMetricOptions(options, method, optimize) {
|
|
|
14
14
|
if (!optimize) {
|
|
15
15
|
throw new TypeError(`${method} options.minimize is not supported because this method returns all routes.`);
|
|
16
16
|
}
|
|
17
|
-
if (options.minimize !== "
|
|
18
|
-
|
|
17
|
+
if (options.minimize !== "steps" && options.minimize !== "weight" &&
|
|
18
|
+
options.minimize !== "elapsedTime") {
|
|
19
|
+
throw new TypeError(`${method} options.minimize must be "steps", "weight", or "elapsedTime".`);
|
|
19
20
|
}
|
|
20
21
|
if (options.minimize === "weight" && options.weight === undefined) {
|
|
21
22
|
throw new TypeError(`${method} options.minimize: "weight" requires options.weight.`);
|
|
@@ -26,7 +27,7 @@ export default function prepareGraphMetricOptions(options, method, optimize) {
|
|
|
26
27
|
}
|
|
27
28
|
if (optimize && elapsedTime && options.weight !== undefined &&
|
|
28
29
|
options.minimize === undefined) {
|
|
29
|
-
throw new TypeError(`${method} when weight and elapsedTime are both enabled, specify options.minimize: "weight" or "elapsedTime".`);
|
|
30
|
+
throw new TypeError(`${method} when weight and elapsedTime are both enabled, specify options.minimize: "steps", "weight", or "elapsedTime".`);
|
|
30
31
|
}
|
|
31
32
|
return {
|
|
32
33
|
elapsedTime,
|
|
@@ -35,6 +36,6 @@ export default function prepareGraphMetricOptions(options, method, optimize) {
|
|
|
35
36
|
? "weight"
|
|
36
37
|
: elapsedTime
|
|
37
38
|
? "elapsedTime"
|
|
38
|
-
: "
|
|
39
|
+
: "steps"),
|
|
39
40
|
};
|
|
40
41
|
}
|
|
@@ -8,13 +8,13 @@ export type PreparedGraphRouteEndpoints = {
|
|
|
8
8
|
/** Prepares and validates the two scalar endpoints shared by route methods. */
|
|
9
9
|
export declare function prepareGraphRouteEndpoints(start: GraphId, end: GraphId, method: string): PreparedGraphRouteEndpoints;
|
|
10
10
|
/** Validates the columns shared by edge-route methods from queued schema data. */
|
|
11
|
-
export declare function validateGraphRouteInputs(schema: TableSchema, source: string, target: string, edgeId: string, endpoints: PreparedGraphRouteEndpoints, weight: string | undefined, method: string): {
|
|
11
|
+
export declare function validateGraphRouteInputs(schema: TableSchema, source: string, target: string, edgeId: string, endpoints: PreparedGraphRouteEndpoints, weight: string | undefined, method: string, includeTotal?: boolean): {
|
|
12
12
|
distanceType: string;
|
|
13
13
|
edgeIdType: string;
|
|
14
14
|
nodeIdType: string;
|
|
15
15
|
};
|
|
16
16
|
/** Prepares the typed SQL expressions shared by edge-route enumeration. */
|
|
17
|
-
export declare function prepareGraphRouteSql(input: string, schema: TableSchema, source: string, target: string, edgeId: string, endpoints: PreparedGraphRouteEndpoints, weight: string | undefined, method: string): {
|
|
17
|
+
export declare function prepareGraphRouteSql(input: string, schema: TableSchema, source: string, target: string, edgeId: string, endpoints: PreparedGraphRouteEndpoints, weight: string | undefined, method: string, includeTotal?: boolean): {
|
|
18
18
|
distanceType: string;
|
|
19
19
|
edgeIdColumn: import("./getGraphEdgeIdColumn.js").GraphEdgeIdColumn;
|
|
20
20
|
edgeKey: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prepareGraphRouteSql.d.ts","sourceRoot":"","sources":["../../src/helpers/prepareGraphRouteSql.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAEnD,OAA2B,EACzB,KAAK,OAAO,EACZ,KAAK,mBAAmB,EACzB,MAAM,yBAAyB,CAAC;AAMjC,MAAM,MAAM,2BAA2B,GAAG;IACxC,GAAG,EAAE,mBAAmB,CAAC;IACzB,KAAK,EAAE,mBAAmB,CAAC;IAC3B,MAAM,EAAE,mBAAmB,CAAC;CAC7B,CAAC;AAEF,+EAA+E;AAC/E,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,OAAO,EACd,GAAG,EAAE,OAAO,EACZ,MAAM,EAAE,MAAM,GACb,2BAA2B,CA+B7B;AAED,kFAAkF;AAClF,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,WAAW,EACnB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,2BAA2B,EACtC,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,MAAM,EAAE,MAAM;;;;
|
|
1
|
+
{"version":3,"file":"prepareGraphRouteSql.d.ts","sourceRoot":"","sources":["../../src/helpers/prepareGraphRouteSql.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAEnD,OAA2B,EACzB,KAAK,OAAO,EACZ,KAAK,mBAAmB,EACzB,MAAM,yBAAyB,CAAC;AAMjC,MAAM,MAAM,2BAA2B,GAAG;IACxC,GAAG,EAAE,mBAAmB,CAAC;IACzB,KAAK,EAAE,mBAAmB,CAAC;IAC3B,MAAM,EAAE,mBAAmB,CAAC;CAC7B,CAAC;AAEF,+EAA+E;AAC/E,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,OAAO,EACd,GAAG,EAAE,OAAO,EACZ,MAAM,EAAE,MAAM,GACb,2BAA2B,CA+B7B;AAED,kFAAkF;AAClF,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,WAAW,EACnB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,2BAA2B,EACtC,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,MAAM,EAAE,MAAM,EACd,YAAY,UAAO;;;;EAmBpB;AAED,2EAA2E;AAC3E,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,WAAW,EACnB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,2BAA2B,EACtC,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,MAAM,EAAE,MAAM,EACd,YAAY,UAAO;;;;;;;;;;;;;EAkDpB"}
|
|
@@ -34,13 +34,13 @@ export function prepareGraphRouteEndpoints(start, end, method) {
|
|
|
34
34
|
};
|
|
35
35
|
}
|
|
36
36
|
/** Validates the columns shared by edge-route methods from queued schema data. */
|
|
37
|
-
export function validateGraphRouteInputs(schema, source, target, edgeId, endpoints, weight, method) {
|
|
37
|
+
export function validateGraphRouteInputs(schema, source, target, edgeId, endpoints, weight, method, includeTotal = true) {
|
|
38
38
|
const nodes = validateGraphStarts(schema, source, target, endpoints.values, method);
|
|
39
39
|
const edges = getGraphEdgeIdColumn(schema, edgeId, method);
|
|
40
40
|
const weightColumn = weight === undefined
|
|
41
41
|
? undefined
|
|
42
42
|
: getGraphWeightColumn(schema, weight, method);
|
|
43
|
-
validateGraphRouteResultSchema(schema, method);
|
|
43
|
+
validateGraphRouteResultSchema(schema, method, [], includeTotal);
|
|
44
44
|
return {
|
|
45
45
|
distanceType: weightColumn?.distanceType ?? "BIGINT",
|
|
46
46
|
edgeIdType: edges.idType,
|
|
@@ -48,8 +48,8 @@ export function validateGraphRouteInputs(schema, source, target, edgeId, endpoin
|
|
|
48
48
|
};
|
|
49
49
|
}
|
|
50
50
|
/** Prepares the typed SQL expressions shared by edge-route enumeration. */
|
|
51
|
-
export function prepareGraphRouteSql(input, schema, source, target, edgeId, endpoints, weight, method) {
|
|
52
|
-
validateGraphRouteResultSchema(schema, method);
|
|
51
|
+
export function prepareGraphRouteSql(input, schema, source, target, edgeId, endpoints, weight, method, includeTotal = true) {
|
|
52
|
+
validateGraphRouteResultSchema(schema, method, [], includeTotal);
|
|
53
53
|
const traversal = prepareGraphTraversal(input, schema, source, target, endpoints.values, method);
|
|
54
54
|
const edgeIdColumn = getGraphEdgeIdColumn(schema, edgeId, method);
|
|
55
55
|
const weightColumn = weight === undefined
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { TableSchema } from "./pendingOps.js";
|
|
2
2
|
/** Validates that route result columns do not replace original input columns. */
|
|
3
|
-
export default function validateGraphRouteResultSchema(schema: TableSchema, method: string, additionalResultColumns?: readonly string[]): void;
|
|
3
|
+
export default function validateGraphRouteResultSchema(schema: TableSchema, method: string, additionalResultColumns?: readonly string[], includeTotal?: boolean): void;
|
|
4
4
|
//# sourceMappingURL=validateGraphRouteResultSchema.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validateGraphRouteResultSchema.d.ts","sourceRoot":"","sources":["../../src/helpers/validateGraphRouteResultSchema.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAKnD,iFAAiF;AACjF,MAAM,CAAC,OAAO,UAAU,8BAA8B,CACpD,MAAM,EAAE,WAAW,EACnB,MAAM,EAAE,MAAM,EACd,uBAAuB,GAAE,SAAS,MAAM,EAAO,
|
|
1
|
+
{"version":3,"file":"validateGraphRouteResultSchema.d.ts","sourceRoot":"","sources":["../../src/helpers/validateGraphRouteResultSchema.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAKnD,iFAAiF;AACjF,MAAM,CAAC,OAAO,UAAU,8BAA8B,CACpD,MAAM,EAAE,WAAW,EACnB,MAAM,EAAE,MAAM,EACd,uBAAuB,GAAE,SAAS,MAAM,EAAO,EAC/C,YAAY,UAAO,GAClB,IAAI,CAmBN"}
|
|
@@ -2,8 +2,10 @@ import foldIdentifier from "./foldIdentifier.js";
|
|
|
2
2
|
import quoteIdentifier from "./quoteIdentifier.js";
|
|
3
3
|
const resultColumns = ["pathId", "step", "weight", "total"];
|
|
4
4
|
/** Validates that route result columns do not replace original input columns. */
|
|
5
|
-
export default function validateGraphRouteResultSchema(schema, method, additionalResultColumns = []) {
|
|
5
|
+
export default function validateGraphRouteResultSchema(schema, method, additionalResultColumns = [], includeTotal = true) {
|
|
6
6
|
for (const resultColumn of [...resultColumns, ...additionalResultColumns]) {
|
|
7
|
+
if (resultColumn === "total" && !includeTotal)
|
|
8
|
+
continue;
|
|
7
9
|
const folded = foldIdentifier(resultColumn);
|
|
8
10
|
const inputColumn = Object.keys(schema).find((column) => foldIdentifier(column) === folded);
|
|
9
11
|
if (inputColumn !== undefined) {
|
|
@@ -7,7 +7,7 @@ type DistancesOptions = GraphTemporalOptions & {
|
|
|
7
7
|
outputTable?: string | boolean;
|
|
8
8
|
weight?: string;
|
|
9
9
|
elapsedTime?: boolean;
|
|
10
|
-
minimize?: "weight" | "elapsedTime";
|
|
10
|
+
minimize?: "steps" | "weight" | "elapsedTime";
|
|
11
11
|
};
|
|
12
12
|
export default function distances(simpleTable: SimpleTable, sourceColumn: string, targetColumn: string, startNodes: GraphId | GraphId[], options?: DistancesOptions): SimpleTable;
|
|
13
13
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"distances.d.ts","sourceRoot":"","sources":["../../src/methods/distances.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,WAAW,MAAM,yBAAyB,CAAC;AAOvD,OAAgC,EAC9B,KAAK,oBAAoB,EAG1B,MAAM,uCAAuC,CAAC;AAC/C,OAA2B,EACzB,KAAK,OAAO,EAEb,MAAM,kCAAkC,CAAC;AAC1C,OAA8B,EAC5B,KAAK,cAAc,EAEpB,MAAM,qCAAqC,CAAC;AAK7C,KAAK,gBAAgB,GAAG,oBAAoB,GAAG;IAC7C,SAAS,CAAC,EAAE,cAAc,CAAC;IAC3B,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,EAAE,QAAQ,GAAG,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"distances.d.ts","sourceRoot":"","sources":["../../src/methods/distances.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,WAAW,MAAM,yBAAyB,CAAC;AAOvD,OAAgC,EAC9B,KAAK,oBAAoB,EAG1B,MAAM,uCAAuC,CAAC;AAC/C,OAA2B,EACzB,KAAK,OAAO,EAEb,MAAM,kCAAkC,CAAC;AAC1C,OAA8B,EAC5B,KAAK,cAAc,EAEpB,MAAM,qCAAqC,CAAC;AAK7C,KAAK,gBAAgB,GAAG,oBAAoB,GAAG;IAC7C,SAAS,CAAC,EAAE,cAAc,CAAC;IAC3B,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,aAAa,CAAC;CAC/C,CAAC;AAEF,MAAM,CAAC,OAAO,UAAU,SAAS,CAC/B,WAAW,EAAE,WAAW,EACxB,YAAY,EAAE,MAAM,EACpB,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,OAAO,GAAG,OAAO,EAAE,EAC/B,OAAO,GAAE,gBAAqB,GAC7B,WAAW,CA+Gb"}
|
package/esm/methods/distances.js
CHANGED
|
@@ -59,7 +59,10 @@ export default function distances(simpleTable, sourceColumn, targetColumn, start
|
|
|
59
59
|
return {
|
|
60
60
|
start: validated.idType,
|
|
61
61
|
node: validated.idType,
|
|
62
|
-
|
|
62
|
+
steps: "BIGINT",
|
|
63
|
+
...(options.weight === undefined
|
|
64
|
+
? {}
|
|
65
|
+
: { total: validated.distanceType }),
|
|
63
66
|
...(metrics.elapsedTime ? { elapsedTimeMs: "DOUBLE" } : {}),
|
|
64
67
|
};
|
|
65
68
|
},
|
|
@@ -84,12 +87,14 @@ function distancesSelect(input, schema, source, target, starts, direction, weigh
|
|
|
84
87
|
const edgeWeight = weightColumn === undefined
|
|
85
88
|
? `CAST(1 AS ${distanceType})`
|
|
86
89
|
: `CAST(${quoteIdentifier("edges")}.${quoteIdentifier(weightColumn.column)} AS ${distanceType})`;
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
90
|
+
const temporal = temporalOptions === undefined
|
|
91
|
+
? undefined
|
|
92
|
+
: prepareGraphTemporalSql(schema, temporalOptions, "distances()");
|
|
93
|
+
if (weight !== undefined || metrics.elapsedTime) {
|
|
94
|
+
return summaryDistancesSelect(prepared, direction, temporal, distanceType, edgeWeight, metrics, weight !== undefined, weightColumn?.type === "FLOAT" || weightColumn?.type === "DOUBLE");
|
|
95
|
+
}
|
|
96
|
+
if (temporal !== undefined) {
|
|
97
|
+
return temporalDistancesSelect(prepared, direction, temporal, distanceType, edgeWeight, "steps", false);
|
|
93
98
|
}
|
|
94
99
|
const relations = prepared.relationNames([
|
|
95
100
|
"graph_start_values",
|
|
@@ -113,6 +118,14 @@ function distancesSelect(input, schema, source, target, starts, direction, weigh
|
|
|
113
118
|
const edgeCost = `${quoteIdentifier("edges")}.${quoteIdentifier("__weight")}`;
|
|
114
119
|
const bestDistance = `${quoteIdentifier("best")}.${quoteIdentifier("distance")}`;
|
|
115
120
|
const candidateDistance = `CAST(${reachedDistance} + ${edgeCost} AS ${distanceType})`;
|
|
121
|
+
const candidateSteps = `${quoteIdentifier("reached")}.${quoteIdentifier("steps")} + 1`;
|
|
122
|
+
const bestSteps = `${quoteIdentifier("best")}.${quoteIdentifier("steps")}`;
|
|
123
|
+
const order = (distance, steps) => metrics.minimize === "steps"
|
|
124
|
+
? `ROW(${steps}, ${distance})`
|
|
125
|
+
: `ROW(${distance}, ${steps})`;
|
|
126
|
+
const candidateOrder = order(candidateDistance, candidateSteps);
|
|
127
|
+
const selectedDistance = `arg_min(${candidateDistance}, ${candidateOrder})`;
|
|
128
|
+
const selectedSteps = `arg_min(${candidateSteps}, ${candidateOrder})`;
|
|
116
129
|
return `WITH RECURSIVE ${startValuesRelation}(${quoteIdentifier("start")}) AS (
|
|
117
130
|
VALUES ${prepared.startValues}
|
|
118
131
|
), ${startsRelation} AS (
|
|
@@ -126,19 +139,20 @@ function distancesSelect(input, schema, source, target, starts, direction, weigh
|
|
|
126
139
|
), ${distancesRelation}(
|
|
127
140
|
${quoteIdentifier("start")}, ${quoteIdentifier("node")},
|
|
128
141
|
${quoteIdentifier("__start_key")}, ${quoteIdentifier("__node_key")},
|
|
129
|
-
${quoteIdentifier("distance")}
|
|
142
|
+
${quoteIdentifier("distance")}, ${quoteIdentifier("steps")}
|
|
130
143
|
) USING KEY(
|
|
131
144
|
${quoteIdentifier("__start_key")}, ${quoteIdentifier("__node_key")}
|
|
132
145
|
) AS (
|
|
133
146
|
SELECT ${start}, ${edgeTo}, ${startKey}, ${edgeToKey},
|
|
134
|
-
MIN(${edgeCost}) AS ${quoteIdentifier("distance")}
|
|
147
|
+
MIN(${edgeCost}) AS ${quoteIdentifier("distance")}, CAST(1 AS BIGINT)
|
|
135
148
|
FROM ${startsRelation} AS ${quoteIdentifier("starts")}
|
|
136
149
|
INNER JOIN ${edgesRelation} AS ${quoteIdentifier("edges")}
|
|
137
150
|
ON ${startKey} = ${edgeFromKey}
|
|
138
151
|
GROUP BY ${start}, ${edgeTo}, ${startKey}, ${edgeToKey}
|
|
139
152
|
UNION
|
|
140
153
|
SELECT ${reachedStart}, ${edgeTo}, ${reachedStartKey}, ${edgeToKey},
|
|
141
|
-
|
|
154
|
+
${selectedDistance} AS ${quoteIdentifier("distance")},
|
|
155
|
+
${selectedSteps} AS ${quoteIdentifier("steps")}
|
|
142
156
|
FROM ${distancesRelation} AS ${quoteIdentifier("reached")}
|
|
143
157
|
INNER JOIN ${edgesRelation} AS ${quoteIdentifier("edges")}
|
|
144
158
|
ON ${reachedNodeKey} = ${edgeFromKey}
|
|
@@ -146,111 +160,259 @@ function distancesSelect(input, schema, source, target, starts, direction, weigh
|
|
|
146
160
|
ON ${reachedStartKey} = ${quoteIdentifier("best")}.${quoteIdentifier("__start_key")}
|
|
147
161
|
AND ${edgeToKey} = ${quoteIdentifier("best")}.${quoteIdentifier("__node_key")}
|
|
148
162
|
GROUP BY ${reachedStart}, ${edgeTo}, ${reachedStartKey}, ${edgeToKey},
|
|
149
|
-
${bestDistance}
|
|
150
|
-
HAVING ${bestDistance} IS NULL OR
|
|
163
|
+
${bestDistance}, ${bestSteps}
|
|
164
|
+
HAVING ${bestDistance} IS NULL OR
|
|
165
|
+
${order(selectedDistance, selectedSteps)} < ${order(bestDistance, bestSteps)}
|
|
151
166
|
)
|
|
152
167
|
SELECT ${quoteIdentifier("start")}, ${quoteIdentifier("node")},
|
|
153
|
-
${quoteIdentifier("
|
|
168
|
+
${quoteIdentifier("steps")}${weight === undefined
|
|
169
|
+
? ""
|
|
170
|
+
: `, ${quoteIdentifier("distance")} AS ${quoteIdentifier("total")}`}
|
|
154
171
|
FROM ${distancesRelation}
|
|
155
|
-
ORDER BY ${quoteIdentifier("__start_key")}, ${quoteIdentifier("distance")}, ${quoteIdentifier("__node_key")}`;
|
|
172
|
+
ORDER BY ${quoteIdentifier("__start_key")}, ${quoteIdentifier(metrics.minimize === "steps" ? "steps" : "distance")}, ${quoteIdentifier("__node_key")}`;
|
|
156
173
|
}
|
|
157
|
-
function temporalDistancesSelect(prepared, direction, temporal, distanceType, edgeWeight) {
|
|
174
|
+
function temporalDistancesSelect(prepared, direction, temporal, distanceType, edgeWeight, minimize, includeTotal) {
|
|
158
175
|
const q = quoteIdentifier;
|
|
159
176
|
const startsSelect = `SELECT ${q("start")},
|
|
160
177
|
${prepared.key(q("start"))} AS ${q("__key")}
|
|
161
178
|
FROM (VALUES ${prepared.startValues}) AS ${q("start_values")}(${q("start")})`;
|
|
162
|
-
const costStates = buildGraphTemporalCostStateSql(prepared, startsSelect, direction, temporal, distanceType, edgeWeight);
|
|
179
|
+
const costStates = buildGraphTemporalCostStateSql(prepared, startsSelect, direction, temporal, distanceType, edgeWeight, [], minimize);
|
|
180
|
+
const order = minimize === "steps"
|
|
181
|
+
? `${q("steps")}, ${q("distance")}`
|
|
182
|
+
: `${q("distance")}, ${q("steps")}`;
|
|
163
183
|
return `${costStates.withClause}
|
|
164
|
-
SELECT ${q("start")}, ${q("node")},
|
|
165
|
-
MIN(${q("distance")}) AS ${q("total")}
|
|
184
|
+
SELECT ${q("start")}, ${q("node")}, ${q("steps")}${includeTotal ? `, ${q("distance")} AS ${q("total")}` : ""}
|
|
166
185
|
FROM ${costStates.costRelation}
|
|
167
|
-
|
|
168
|
-
${q("__node_key")}
|
|
169
|
-
|
|
186
|
+
QUALIFY row_number() OVER (
|
|
187
|
+
PARTITION BY ${q("__start_key")}, ${q("__node_key")}
|
|
188
|
+
ORDER BY ${order}
|
|
189
|
+
) = 1
|
|
190
|
+
ORDER BY ${q("__start_key")}, ${q(minimize === "steps" ? "steps" : "distance")}, ${q("__node_key")}`;
|
|
170
191
|
}
|
|
171
|
-
|
|
192
|
+
// Distinct visited sets, metrics, and temporal boundaries are enough to extend
|
|
193
|
+
// summaries. No edge IDs or full connection sequences are needed. Keeping the
|
|
194
|
+
// visited set is necessary: equal summaries can have different legal extensions.
|
|
195
|
+
function summaryDistancesSelect(prepared, direction, temporal, distanceType, edgeWeight, metrics, includeTotal, floatingWeight) {
|
|
172
196
|
const q = quoteIdentifier;
|
|
173
197
|
const relations = prepared.relationNames([
|
|
174
198
|
"graph_starts",
|
|
175
199
|
"graph_temporal_settings",
|
|
176
200
|
"graph_event_rows",
|
|
177
201
|
"graph_edges",
|
|
178
|
-
"
|
|
179
|
-
"
|
|
202
|
+
"graph_summaries",
|
|
203
|
+
"graph_metric_results",
|
|
204
|
+
"graph_tied_summaries",
|
|
205
|
+
"graph_best_metrics",
|
|
206
|
+
"graph_metric_bounds",
|
|
180
207
|
]);
|
|
181
208
|
const starts = relations.graph_starts;
|
|
182
209
|
const settings = relations.graph_temporal_settings;
|
|
183
210
|
const events = relations.graph_event_rows;
|
|
184
211
|
const edges = relations.graph_edges;
|
|
185
|
-
const
|
|
186
|
-
const results = relations.
|
|
212
|
+
const summaries = relations.graph_summaries;
|
|
213
|
+
const results = relations.graph_metric_results;
|
|
214
|
+
const tied = relations.graph_tied_summaries;
|
|
187
215
|
const ref = (alias, column) => `${q(alias)}.${q(column)}`;
|
|
188
|
-
const
|
|
189
|
-
const
|
|
190
|
-
const
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
216
|
+
const searchDirection = direction;
|
|
217
|
+
const firstAnchor = temporal?.journeyAnchor("edges", searchDirection);
|
|
218
|
+
const sum = `CAST(${ref("reached", "distance")} + ${ref("edges", "__weight")} AS ${distanceType})`;
|
|
219
|
+
// Reported costs must not reject routes before the primary objective has
|
|
220
|
+
// selected its results. NULL marks overflow and propagates through sums;
|
|
221
|
+
// non-negative weights cannot bring an overflowing total back into range.
|
|
222
|
+
const nextDistance = metrics.minimize === "weight" ? sum : `TRY(${sum})`;
|
|
223
|
+
const temporalColumns = temporal === undefined
|
|
224
|
+
? ""
|
|
225
|
+
: `, ${q("__event_start")}, ${q("__event_end")}`;
|
|
226
|
+
const eventValues = temporal === undefined
|
|
227
|
+
? ""
|
|
228
|
+
: `, ${ref("edges", "__event_start")}, ${ref("edges", "__event_end")}`;
|
|
229
|
+
const metric = metrics.minimize === "steps"
|
|
230
|
+
? q("steps")
|
|
231
|
+
: metrics.minimize === "weight"
|
|
232
|
+
? q("distance")
|
|
233
|
+
: q("__elapsed");
|
|
234
|
+
// Use native time precision for selection. Collapse equal reported values
|
|
235
|
+
// after conversion to milliseconds, since these are summary rows.
|
|
236
|
+
const reportedElapsed = metrics.elapsedTime
|
|
237
|
+
? `, ${temporal.elapsedMilliseconds(q("__elapsed"))} AS ${q("elapsedTimeMs")}`
|
|
238
|
+
: "";
|
|
239
|
+
const order = metrics.minimize === "steps"
|
|
240
|
+
? [
|
|
241
|
+
q("steps"),
|
|
242
|
+
q("__node_key"),
|
|
243
|
+
...(includeTotal ? [q("total")] : []),
|
|
244
|
+
...(metrics.elapsedTime ? [q("elapsedTimeMs")] : []),
|
|
245
|
+
]
|
|
246
|
+
: metrics.minimize === "weight"
|
|
247
|
+
? [
|
|
248
|
+
q("total"),
|
|
249
|
+
q("__node_key"),
|
|
250
|
+
q("steps"),
|
|
251
|
+
...(metrics.elapsedTime ? [q("elapsedTimeMs")] : []),
|
|
252
|
+
]
|
|
253
|
+
: [
|
|
254
|
+
q("elapsedTimeMs"),
|
|
255
|
+
q("__node_key"),
|
|
256
|
+
q("steps"),
|
|
257
|
+
...(includeTotal ? [q("total")] : []),
|
|
258
|
+
];
|
|
259
|
+
const bounds = summaryBoundsSql(relations.graph_best_metrics, relations.graph_metric_bounds, starts, edges, settings, temporal, searchDirection, metrics.minimize, distanceType, floatingWeight);
|
|
260
|
+
return `WITH RECURSIVE ${settings} AS (
|
|
261
|
+
${temporal === undefined
|
|
262
|
+
? `SELECT 0 AS ${q("__gap")}`
|
|
263
|
+
: `SELECT CAST(? AS HUGEINT) AS ${q("__gap")}`}
|
|
200
264
|
), ${events} AS MATERIALIZED (
|
|
201
265
|
${prepared.edges(direction, [
|
|
202
266
|
`${edgeWeight} AS ${q("__weight")}`,
|
|
203
|
-
...temporal
|
|
267
|
+
...(temporal?.eventSelections("edges") ?? []),
|
|
204
268
|
])}
|
|
205
269
|
), ${edges} AS MATERIALIZED (
|
|
206
|
-
SELECT
|
|
207
|
-
|
|
208
|
-
|
|
270
|
+
SELECT DISTINCT ${q("__from")}, ${q("__to")}, ${q("__from_key")},
|
|
271
|
+
${q("__to_key")}, ${q("__weight")}${temporalColumns}
|
|
272
|
+
FROM ${events} AS ${q("events")}
|
|
273
|
+
${temporal === undefined ? "" : `WHERE ${temporal.eventValidity("events")}`}
|
|
274
|
+
), ${starts} AS (
|
|
209
275
|
SELECT ${q("start")}, ${prepared.key(q("start"))} AS ${q("__key")}
|
|
210
276
|
FROM (VALUES ${prepared.startValues}) AS ${q("start_values")}(${q("start")})
|
|
211
|
-
), ${
|
|
277
|
+
), ${bounds.ctes}, ${summaries}(
|
|
212
278
|
${q("start")}, ${q("node")}, ${q("__start_key")}, ${q("__node_key")},
|
|
213
|
-
${q("
|
|
214
|
-
|
|
215
|
-
) USING KEY(${q("__start_key")}, ${q("__event_id")}, ${q("__anchor")}) AS (
|
|
279
|
+
${q("__visited")}, ${q("steps")}, ${q("distance")}${temporalColumns}${metrics.elapsedTime ? `, ${q("__anchor")}` : ""}
|
|
280
|
+
) AS (
|
|
216
281
|
SELECT ${ref("starts", "start")}, ${ref("edges", "__to")},
|
|
217
282
|
${ref("starts", "__key")}, ${ref("edges", "__to_key")},
|
|
218
|
-
${ref("
|
|
219
|
-
${ref("edges", "
|
|
283
|
+
list_sort(list_distinct([${ref("starts", "__key")}, ${ref("edges", "__to_key")}])),
|
|
284
|
+
CAST(1 AS BIGINT), ${ref("edges", "__weight")}${eventValues}${metrics.elapsedTime ? `, ${firstAnchor}` : ""}
|
|
220
285
|
FROM ${starts} AS ${q("starts")}
|
|
221
286
|
INNER JOIN ${edges} AS ${q("edges")}
|
|
222
287
|
ON ${ref("starts", "__key")} = ${ref("edges", "__from_key")}
|
|
288
|
+
${bounds.join(ref("starts", "__key"))}
|
|
289
|
+
WHERE ${bounds.test("CAST(1 AS BIGINT)", ref("edges", "__weight"), firstAnchor)}
|
|
223
290
|
UNION
|
|
224
291
|
SELECT ${ref("reached", "start")}, ${ref("edges", "__to")},
|
|
225
292
|
${ref("reached", "__start_key")}, ${ref("edges", "__to_key")},
|
|
226
|
-
${ref("
|
|
227
|
-
${ref("
|
|
228
|
-
|
|
229
|
-
FROM ${states} AS ${q("reached")}
|
|
293
|
+
list_sort(list_distinct(list_append(${ref("reached", "__visited")}, ${ref("edges", "__to_key")}))),
|
|
294
|
+
${ref("reached", "steps")} + 1, ${nextDistance}${eventValues}${metrics.elapsedTime ? `, ${ref("reached", "__anchor")}` : ""}
|
|
295
|
+
FROM ${summaries} AS ${q("reached")}
|
|
230
296
|
INNER JOIN ${edges} AS ${q("edges")}
|
|
231
297
|
ON ${ref("reached", "__node_key")} = ${ref("edges", "__from_key")}
|
|
232
298
|
CROSS JOIN ${settings} AS ${q("settings")}
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
AND ${ref("
|
|
236
|
-
AND ${
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
${ref("reached", "__start_key")}, ${ref("edges", "__to_key")},
|
|
240
|
-
${ref("edges", "__event_id")}, ${ref("edges", "__event_start")},
|
|
241
|
-
${ref("edges", "__event_end")}, ${reachedAnchor}, ${ref("best", "distance")}
|
|
242
|
-
HAVING ${ref("best", "distance")} IS NULL OR
|
|
243
|
-
MIN(${candidateDistance}) < ${ref("best", "distance")}
|
|
299
|
+
${bounds.join(ref("reached", "__start_key"))}
|
|
300
|
+
WHERE ${bounds.test(`${ref("reached", "steps")} + 1`, nextDistance, ref("reached", "__anchor"))}
|
|
301
|
+
AND ${ref("reached", "__node_key")} <> ${ref("reached", "__start_key")}
|
|
302
|
+
AND (NOT list_contains(${ref("reached", "__visited")}, ${ref("edges", "__to_key")})
|
|
303
|
+
OR ${ref("edges", "__to_key")} = ${ref("reached", "__start_key")})
|
|
304
|
+
${temporal === undefined ? "" : `AND ${temporal.transition("reached", "edges", searchDirection, ref("settings", "__gap"))}`}
|
|
244
305
|
), ${results} AS (
|
|
245
|
-
SELECT
|
|
246
|
-
|
|
306
|
+
SELECT *${metrics.elapsedTime
|
|
307
|
+
? `, ${temporal.journeyElapsed("summaries", ref("summaries", "__anchor"), searchDirection)} AS ${q("__elapsed")}`
|
|
308
|
+
: ""}
|
|
309
|
+
FROM ${summaries} AS ${q("summaries")}
|
|
310
|
+
), ${tied} AS MATERIALIZED (
|
|
311
|
+
SELECT DISTINCT ${q("start")}, ${q("node")}, ${q("__start_key")}, ${q("__node_key")},
|
|
312
|
+
${q("steps")}${includeTotal ? `, ${q("distance")} AS ${q("total")}` : ""}${reportedElapsed}
|
|
313
|
+
FROM ${results}
|
|
314
|
+
QUALIFY ${metric} = MIN(${metric}) OVER (
|
|
315
|
+
PARTITION BY ${q("__start_key")}, ${q("__node_key")}
|
|
316
|
+
)
|
|
247
317
|
)
|
|
248
|
-
SELECT ${q("start")}, ${q("node")}, ${q("
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
)
|
|
255
|
-
|
|
318
|
+
SELECT ${q("start")}, ${q("node")}, ${q("steps")}${includeTotal
|
|
319
|
+
? `, CASE WHEN ${q("total")} IS NULL
|
|
320
|
+
THEN error('distances() total exceeds the supported ${distanceType} range for an optimal route.')
|
|
321
|
+
ELSE ${q("total")} END AS ${q("total")}`
|
|
322
|
+
: ""}${metrics.elapsedTime ? `, ${q("elapsedTimeMs")}` : ""}
|
|
323
|
+
FROM ${tied}
|
|
324
|
+
ORDER BY ${q("__start_key")}, ${order.join(", ")}`;
|
|
325
|
+
}
|
|
326
|
+
// Compute primary optima without enumerating visited sets. Exact additive
|
|
327
|
+
// objectives have optimal prefixes (at the same event boundary in temporal
|
|
328
|
+
// traversal). Floating addition can erase prefix differences, and elapsed
|
|
329
|
+
// optima can depend on a later departure, so those use a per-start upper bound.
|
|
330
|
+
function summaryBoundsSql(best, limits, starts, edges, settings, temporal, direction, minimize, distanceType, floatingWeight) {
|
|
331
|
+
const q = quoteIdentifier;
|
|
332
|
+
const ref = (alias, column) => `${q(alias)}.${q(column)}`;
|
|
333
|
+
const elapsed = minimize === "elapsedTime";
|
|
334
|
+
const globalBound = elapsed || (minimize === "weight" && floatingWeight);
|
|
335
|
+
const boundaries = temporal === undefined
|
|
336
|
+
? []
|
|
337
|
+
: ["__event_start", "__event_end"];
|
|
338
|
+
const keys = [
|
|
339
|
+
"__start_key",
|
|
340
|
+
"__node_key",
|
|
341
|
+
...boundaries,
|
|
342
|
+
...(elapsed ? ["__anchor"] : []),
|
|
343
|
+
];
|
|
344
|
+
const firstAnchor = elapsed
|
|
345
|
+
? temporal.journeyAnchor("edges", direction)
|
|
346
|
+
: undefined;
|
|
347
|
+
const firstKeys = [
|
|
348
|
+
ref("starts", "__key"),
|
|
349
|
+
ref("edges", "__to_key"),
|
|
350
|
+
...boundaries.map((key) => ref("edges", key)),
|
|
351
|
+
...(elapsed ? [firstAnchor] : []),
|
|
352
|
+
];
|
|
353
|
+
const nextKeys = [
|
|
354
|
+
ref("reached", "__start_key"),
|
|
355
|
+
ref("edges", "__to_key"),
|
|
356
|
+
...boundaries.map((key) => ref("edges", key)),
|
|
357
|
+
...(elapsed ? [ref("reached", "__anchor")] : []),
|
|
358
|
+
];
|
|
359
|
+
const firstMetric = minimize === "steps"
|
|
360
|
+
? "CAST(1 AS BIGINT)"
|
|
361
|
+
: elapsed
|
|
362
|
+
? temporal.journeyElapsed("edges", firstAnchor, direction)
|
|
363
|
+
: ref("edges", "__weight");
|
|
364
|
+
const nextMetric = minimize === "steps"
|
|
365
|
+
? `${ref("reached", "__metric")} + 1`
|
|
366
|
+
: elapsed
|
|
367
|
+
? temporal.journeyElapsed("edges", ref("reached", "__anchor"), direction)
|
|
368
|
+
: `CAST(${ref("reached", "__metric")} + ${ref("edges", "__weight")} AS ${distanceType})`;
|
|
369
|
+
const minimum = `MIN(${nextMetric})`;
|
|
370
|
+
const bestMetric = ref("best", "__metric");
|
|
371
|
+
const ctes = `${best}(${keys.map(q).join(", ")}, ${q("__metric")})
|
|
372
|
+
USING KEY(${keys.map(q).join(", ")}) AS (
|
|
373
|
+
SELECT ${firstKeys.join(", ")}, MIN(${firstMetric})
|
|
374
|
+
FROM ${starts} AS ${q("starts")}
|
|
375
|
+
INNER JOIN ${edges} AS ${q("edges")}
|
|
376
|
+
ON ${ref("starts", "__key")} = ${ref("edges", "__from_key")}
|
|
377
|
+
GROUP BY ${firstKeys.join(", ")}
|
|
378
|
+
UNION
|
|
379
|
+
SELECT ${nextKeys.join(", ")}, ${minimum}
|
|
380
|
+
FROM ${best} AS ${q("reached")}
|
|
381
|
+
INNER JOIN ${edges} AS ${q("edges")}
|
|
382
|
+
ON ${ref("reached", "__node_key")} = ${ref("edges", "__from_key")}
|
|
383
|
+
CROSS JOIN ${settings} AS ${q("settings")}
|
|
384
|
+
LEFT JOIN recurring.${best} AS ${q("best")}
|
|
385
|
+
ON ${keys.map((key, i) => `${ref("best", key)} = ${nextKeys[i]}`).join(" AND ")}
|
|
386
|
+
WHERE ${ref("reached", "__node_key")} <> ${ref("reached", "__start_key")}
|
|
387
|
+
${temporal === undefined ? "" : `AND ${temporal.transition("reached", "edges", direction, ref("settings", "__gap"))}`}
|
|
388
|
+
GROUP BY ${nextKeys.join(", ")}, ${bestMetric}
|
|
389
|
+
HAVING ${bestMetric} IS NULL OR ${minimum} < ${bestMetric}
|
|
390
|
+
)${globalBound
|
|
391
|
+
? `, ${limits} AS (
|
|
392
|
+
SELECT ${q("__start_key")}, MAX(${q("__minimum")}) AS ${q("__metric")}
|
|
393
|
+
FROM (
|
|
394
|
+
SELECT ${q("__start_key")}, ${q("__node_key")}, MIN(${q("__metric")}) AS ${q("__minimum")}
|
|
395
|
+
FROM ${best}
|
|
396
|
+
GROUP BY ${q("__start_key")}, ${q("__node_key")}
|
|
397
|
+
) AS ${q("minima")}
|
|
398
|
+
GROUP BY ${q("__start_key")}
|
|
399
|
+
)`
|
|
400
|
+
: ""}`;
|
|
401
|
+
return {
|
|
402
|
+
ctes,
|
|
403
|
+
join: (startKey) => `INNER JOIN ${globalBound ? limits : best} AS ${q("bounds")}
|
|
404
|
+
ON ${ref("bounds", "__start_key")} = ${startKey}
|
|
405
|
+
${globalBound
|
|
406
|
+
? ""
|
|
407
|
+
: `AND ${ref("bounds", "__node_key")} = ${ref("edges", "__to_key")}
|
|
408
|
+
${boundaries.map((key) => `AND ${ref("bounds", key)} = ${ref("edges", key)}`).join(" ")}`}`,
|
|
409
|
+
test: (steps, distance, anchor) => {
|
|
410
|
+
const metric = minimize === "steps"
|
|
411
|
+
? steps
|
|
412
|
+
: elapsed
|
|
413
|
+
? temporal.journeyElapsed("edges", anchor, direction)
|
|
414
|
+
: distance;
|
|
415
|
+
return `${metric} ${globalBound ? "<=" : "="} ${ref("bounds", "__metric")}`;
|
|
416
|
+
},
|
|
417
|
+
};
|
|
256
418
|
}
|
|
@@ -7,7 +7,7 @@ type ShortestPathOptions = GraphTemporalOptions & {
|
|
|
7
7
|
outputTable?: string | boolean;
|
|
8
8
|
weight?: string;
|
|
9
9
|
elapsedTime?: boolean;
|
|
10
|
-
minimize?: "weight" | "elapsedTime";
|
|
10
|
+
minimize?: "steps" | "weight" | "elapsedTime";
|
|
11
11
|
};
|
|
12
12
|
export default function shortestPath(simpleTable: SimpleTable, sourceColumn: string, targetColumn: string, edgeId: string, start: GraphId, end: GraphId, options?: ShortestPathOptions): SimpleTable;
|
|
13
13
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shortestPath.d.ts","sourceRoot":"","sources":["../../src/methods/shortestPath.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,WAAW,MAAM,yBAAyB,CAAC;AAMvD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kCAAkC,CAAC;AAShE,OAAgC,EAC9B,KAAK,oBAAoB,EAG1B,MAAM,uCAAuC,CAAC;AAC/C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qCAAqC,CAAC;AAK1E,KAAK,mBAAmB,GAAG,oBAAoB,GAAG;IAChD,SAAS,CAAC,EAAE,cAAc,CAAC;IAC3B,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,EAAE,QAAQ,GAAG,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"shortestPath.d.ts","sourceRoot":"","sources":["../../src/methods/shortestPath.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,WAAW,MAAM,yBAAyB,CAAC;AAMvD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kCAAkC,CAAC;AAShE,OAAgC,EAC9B,KAAK,oBAAoB,EAG1B,MAAM,uCAAuC,CAAC;AAC/C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qCAAqC,CAAC;AAK1E,KAAK,mBAAmB,GAAG,oBAAoB,GAAG;IAChD,SAAS,CAAC,EAAE,cAAc,CAAC;IAC3B,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,aAAa,CAAC;CAC/C,CAAC;AAEF,MAAM,CAAC,OAAO,UAAU,YAAY,CAClC,WAAW,EAAE,WAAW,EACxB,YAAY,EAAE,MAAM,EACpB,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,OAAO,EACd,GAAG,EAAE,OAAO,EACZ,OAAO,GAAE,mBAAwB,GAChC,WAAW,CAyHb"}
|