@nicia-ai/typegraph 0.21.0 → 0.22.0
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/backend/postgres/index.cjs +33 -33
- package/dist/backend/postgres/index.js +4 -4
- package/dist/backend/sqlite/index.cjs +14 -14
- package/dist/backend/sqlite/index.d.cts +11 -0
- package/dist/backend/sqlite/index.d.ts +11 -0
- package/dist/backend/sqlite/index.js +4 -4
- package/dist/backend/sqlite/libsql.cjs +7 -7
- package/dist/backend/sqlite/libsql.js +4 -4
- package/dist/backend/sqlite/local.cjs +26 -9
- package/dist/backend/sqlite/local.cjs.map +1 -1
- package/dist/backend/sqlite/local.js +21 -5
- package/dist/backend/sqlite/local.js.map +1 -1
- package/dist/{chunk-FQCQM3KG.cjs → chunk-3JK66E3I.cjs} +4 -2
- package/dist/chunk-3JK66E3I.cjs.map +1 -0
- package/dist/{chunk-SMMOAVJ5.js → chunk-3PPEHLGK.js} +3 -3
- package/dist/{chunk-SMMOAVJ5.js.map → chunk-3PPEHLGK.js.map} +1 -1
- package/dist/{chunk-UQVBVBVG.js → chunk-5ZMMHUWR.js} +53 -7
- package/dist/chunk-5ZMMHUWR.js.map +1 -0
- package/dist/{chunk-4XNE2JG3.js → chunk-753F33CV.js} +4 -2
- package/dist/chunk-753F33CV.js.map +1 -0
- package/dist/{chunk-CQL6FOTT.cjs → chunk-GUYI6VAS.cjs} +43 -24
- package/dist/chunk-GUYI6VAS.cjs.map +1 -0
- package/dist/{chunk-NRNJ52AA.js → chunk-NSLTDXVH.js} +26 -7
- package/dist/chunk-NSLTDXVH.js.map +1 -0
- package/dist/{chunk-2X7P7AD5.cjs → chunk-PEE4EWXZ.cjs} +22 -22
- package/dist/{chunk-2X7P7AD5.cjs.map → chunk-PEE4EWXZ.cjs.map} +1 -1
- package/dist/{chunk-Q73OWTJY.cjs → chunk-SCXOGKLD.cjs} +112 -66
- package/dist/chunk-SCXOGKLD.cjs.map +1 -0
- package/dist/index.cjs +135 -54
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +45 -1
- package/dist/index.d.ts +45 -1
- package/dist/index.js +115 -36
- package/dist/index.js.map +1 -1
- package/dist/indexes/index.cjs +16 -16
- package/dist/indexes/index.js +2 -2
- package/package.json +1 -1
- package/dist/chunk-4XNE2JG3.js.map +0 -1
- package/dist/chunk-CQL6FOTT.cjs.map +0 -1
- package/dist/chunk-FQCQM3KG.cjs.map +0 -1
- package/dist/chunk-NRNJ52AA.js.map +0 -1
- package/dist/chunk-Q73OWTJY.cjs.map +0 -1
- package/dist/chunk-UQVBVBVG.js.map +0 -1
package/dist/index.d.cts
CHANGED
|
@@ -480,6 +480,50 @@ declare function count(alias: string, field?: string): AggregateExpr;
|
|
|
480
480
|
* @param field - Optional field to count distinct values of
|
|
481
481
|
*/
|
|
482
482
|
declare function countDistinct(alias: string, field?: string): AggregateExpr;
|
|
483
|
+
/**
|
|
484
|
+
* Creates a COUNT aggregate expression over an edge alias.
|
|
485
|
+
*
|
|
486
|
+
* Counts edges directly, without joining back to the target node table.
|
|
487
|
+
* This has different semantics from `count(targetAlias)`:
|
|
488
|
+
*
|
|
489
|
+
* - `countEdges(edgeAlias)` — counts live edges, regardless of target-node
|
|
490
|
+
* temporal state. If a target node's `validTo` is in the past while its
|
|
491
|
+
* incident edges are still live, those edges are still counted.
|
|
492
|
+
* - `count(targetAlias)` — counts edges whose target node is currently
|
|
493
|
+
* valid under the query's temporal mode.
|
|
494
|
+
*
|
|
495
|
+
* For the common case ("how many follow relationships does this user
|
|
496
|
+
* have?") the edge-count semantics is what you want, and the compiler
|
|
497
|
+
* can skip the target-node join entirely — measurably faster on
|
|
498
|
+
* full-graph aggregates where the join dominates cost.
|
|
499
|
+
*
|
|
500
|
+
* @example
|
|
501
|
+
* ```typescript
|
|
502
|
+
* store
|
|
503
|
+
* .query()
|
|
504
|
+
* .from("User", "u")
|
|
505
|
+
* .optionalTraverse("follows", "e", { expand: "none" })
|
|
506
|
+
* .to("User", "target")
|
|
507
|
+
* .groupByNode("u")
|
|
508
|
+
* .aggregate({
|
|
509
|
+
* name: field("u", "name"),
|
|
510
|
+
* // counts edges — skips the target-node join
|
|
511
|
+
* followCount: countEdges("e"),
|
|
512
|
+
* })
|
|
513
|
+
* .execute();
|
|
514
|
+
* ```
|
|
515
|
+
*/
|
|
516
|
+
declare function countEdges(edgeAlias: string): AggregateExpr;
|
|
517
|
+
/**
|
|
518
|
+
* Creates a COUNT DISTINCT aggregate expression over an edge alias.
|
|
519
|
+
* See {@link countEdges} for semantics.
|
|
520
|
+
*
|
|
521
|
+
* Distinct-on-edge-id is equivalent to `countEdges` when the query
|
|
522
|
+
* surface produces each edge exactly once, but stays meaningful under
|
|
523
|
+
* polymorphic expansions and ontology-driven edge fan-outs where the
|
|
524
|
+
* same edge can appear multiple times in the join output.
|
|
525
|
+
*/
|
|
526
|
+
declare function countDistinctEdges(edgeAlias: string): AggregateExpr;
|
|
483
527
|
/**
|
|
484
528
|
* Creates a SUM aggregate expression.
|
|
485
529
|
*
|
|
@@ -722,4 +766,4 @@ type IdConfig = Readonly<{
|
|
|
722
766
|
edgeIdGenerator: IdGenerator;
|
|
723
767
|
}>;
|
|
724
768
|
|
|
725
|
-
export { AliasMap, type DefineEdgeOptions, type DefineNodeOptions, EdgeType, type ExternalRefSchema, type ExternalRefValue, FieldRef, type FlexibleQueryFragment, GraphDef, type IdConfig, type IdGenerator, InferenceType, MAX_EXPLICIT_RECURSIVE_DEPTH, MAX_RECURSIVE_DEPTH, MetaEdge, type MetaEdgeOptions, NodeType, OntologyRelation, QueryBuilder, type QueryFragment, type TraversalFragment, avg, broader, composeFragments, core, count, countDistinct, createExternalRef, createFragment, createQueryBuilder, defineEdge, defineNode, differentFrom, disjointWith, equivalentTo, externalRef, field, generateId, getExternalRefTable, hasPart, having, havingEq, havingGt, havingGte, havingLt, havingLte, implies, inverseOf, isExternalRefSchema, limitFragment, max, metaEdge, min, narrower, offsetFragment, orderByFragment, partOf, relatedTo, sameAs, subClassOf, sum };
|
|
769
|
+
export { AliasMap, type DefineEdgeOptions, type DefineNodeOptions, EdgeType, type ExternalRefSchema, type ExternalRefValue, FieldRef, type FlexibleQueryFragment, GraphDef, type IdConfig, type IdGenerator, InferenceType, MAX_EXPLICIT_RECURSIVE_DEPTH, MAX_RECURSIVE_DEPTH, MetaEdge, type MetaEdgeOptions, NodeType, OntologyRelation, QueryBuilder, type QueryFragment, type TraversalFragment, avg, broader, composeFragments, core, count, countDistinct, countDistinctEdges, countEdges, createExternalRef, createFragment, createQueryBuilder, defineEdge, defineNode, differentFrom, disjointWith, equivalentTo, externalRef, field, generateId, getExternalRefTable, hasPart, having, havingEq, havingGt, havingGte, havingLt, havingLte, implies, inverseOf, isExternalRefSchema, limitFragment, max, metaEdge, min, narrower, offsetFragment, orderByFragment, partOf, relatedTo, sameAs, subClassOf, sum };
|
package/dist/index.d.ts
CHANGED
|
@@ -480,6 +480,50 @@ declare function count(alias: string, field?: string): AggregateExpr;
|
|
|
480
480
|
* @param field - Optional field to count distinct values of
|
|
481
481
|
*/
|
|
482
482
|
declare function countDistinct(alias: string, field?: string): AggregateExpr;
|
|
483
|
+
/**
|
|
484
|
+
* Creates a COUNT aggregate expression over an edge alias.
|
|
485
|
+
*
|
|
486
|
+
* Counts edges directly, without joining back to the target node table.
|
|
487
|
+
* This has different semantics from `count(targetAlias)`:
|
|
488
|
+
*
|
|
489
|
+
* - `countEdges(edgeAlias)` — counts live edges, regardless of target-node
|
|
490
|
+
* temporal state. If a target node's `validTo` is in the past while its
|
|
491
|
+
* incident edges are still live, those edges are still counted.
|
|
492
|
+
* - `count(targetAlias)` — counts edges whose target node is currently
|
|
493
|
+
* valid under the query's temporal mode.
|
|
494
|
+
*
|
|
495
|
+
* For the common case ("how many follow relationships does this user
|
|
496
|
+
* have?") the edge-count semantics is what you want, and the compiler
|
|
497
|
+
* can skip the target-node join entirely — measurably faster on
|
|
498
|
+
* full-graph aggregates where the join dominates cost.
|
|
499
|
+
*
|
|
500
|
+
* @example
|
|
501
|
+
* ```typescript
|
|
502
|
+
* store
|
|
503
|
+
* .query()
|
|
504
|
+
* .from("User", "u")
|
|
505
|
+
* .optionalTraverse("follows", "e", { expand: "none" })
|
|
506
|
+
* .to("User", "target")
|
|
507
|
+
* .groupByNode("u")
|
|
508
|
+
* .aggregate({
|
|
509
|
+
* name: field("u", "name"),
|
|
510
|
+
* // counts edges — skips the target-node join
|
|
511
|
+
* followCount: countEdges("e"),
|
|
512
|
+
* })
|
|
513
|
+
* .execute();
|
|
514
|
+
* ```
|
|
515
|
+
*/
|
|
516
|
+
declare function countEdges(edgeAlias: string): AggregateExpr;
|
|
517
|
+
/**
|
|
518
|
+
* Creates a COUNT DISTINCT aggregate expression over an edge alias.
|
|
519
|
+
* See {@link countEdges} for semantics.
|
|
520
|
+
*
|
|
521
|
+
* Distinct-on-edge-id is equivalent to `countEdges` when the query
|
|
522
|
+
* surface produces each edge exactly once, but stays meaningful under
|
|
523
|
+
* polymorphic expansions and ontology-driven edge fan-outs where the
|
|
524
|
+
* same edge can appear multiple times in the join output.
|
|
525
|
+
*/
|
|
526
|
+
declare function countDistinctEdges(edgeAlias: string): AggregateExpr;
|
|
483
527
|
/**
|
|
484
528
|
* Creates a SUM aggregate expression.
|
|
485
529
|
*
|
|
@@ -722,4 +766,4 @@ type IdConfig = Readonly<{
|
|
|
722
766
|
edgeIdGenerator: IdGenerator;
|
|
723
767
|
}>;
|
|
724
768
|
|
|
725
|
-
export { AliasMap, type DefineEdgeOptions, type DefineNodeOptions, EdgeType, type ExternalRefSchema, type ExternalRefValue, FieldRef, type FlexibleQueryFragment, GraphDef, type IdConfig, type IdGenerator, InferenceType, MAX_EXPLICIT_RECURSIVE_DEPTH, MAX_RECURSIVE_DEPTH, MetaEdge, type MetaEdgeOptions, NodeType, OntologyRelation, QueryBuilder, type QueryFragment, type TraversalFragment, avg, broader, composeFragments, core, count, countDistinct, createExternalRef, createFragment, createQueryBuilder, defineEdge, defineNode, differentFrom, disjointWith, equivalentTo, externalRef, field, generateId, getExternalRefTable, hasPart, having, havingEq, havingGt, havingGte, havingLt, havingLte, implies, inverseOf, isExternalRefSchema, limitFragment, max, metaEdge, min, narrower, offsetFragment, orderByFragment, partOf, relatedTo, sameAs, subClassOf, sum };
|
|
769
|
+
export { AliasMap, type DefineEdgeOptions, type DefineNodeOptions, EdgeType, type ExternalRefSchema, type ExternalRefValue, FieldRef, type FlexibleQueryFragment, GraphDef, type IdConfig, type IdGenerator, InferenceType, MAX_EXPLICIT_RECURSIVE_DEPTH, MAX_RECURSIVE_DEPTH, MetaEdge, type MetaEdgeOptions, NodeType, OntologyRelation, QueryBuilder, type QueryFragment, type TraversalFragment, avg, broader, composeFragments, core, count, countDistinct, countDistinctEdges, countEdges, createExternalRef, createFragment, createQueryBuilder, defineEdge, defineNode, differentFrom, disjointWith, equivalentTo, externalRef, field, generateId, getExternalRefTable, hasPart, having, havingEq, havingGt, havingGte, havingLt, havingLte, implies, inverseOf, isExternalRefSchema, limitFragment, max, metaEdge, min, narrower, offsetFragment, orderByFragment, partOf, relatedTo, sameAs, subClassOf, sum };
|
package/dist/index.js
CHANGED
|
@@ -4,8 +4,8 @@ import { NODE_TYPE_BRAND, EDGE_TYPE_BRAND, nowIso, validateOptionalIsoDate, getN
|
|
|
4
4
|
export { defineGraph, getEdgeKinds, getNodeKinds, isEdgeType, isEdgeTypeWithEndpoints, isGraphDef, isNodeType } from './chunk-RS5OLGEW.js';
|
|
5
5
|
import { ConfigurationError, UnsupportedPredicateError, ValidationError, CompilerInvariantError, KindNotFoundError, DatabaseOperationError, EdgeNotFoundError, NodeConstraintNotFoundError, RestrictedDeleteError, NodeNotFoundError, EndpointNotFoundError, UniquenessError, CardinalityError, EndpointError, DisjointError } from './chunk-WFMTAEEN.js';
|
|
6
6
|
export { BackendDisposedError, CardinalityError, CompilerInvariantError, ConfigurationError, DatabaseOperationError, DisjointError, EdgeNotFoundError, EndpointError, EndpointNotFoundError, KindNotFoundError, MigrationError, NodeConstraintNotFoundError, NodeNotFoundError, RestrictedDeleteError, SchemaMismatchError, TypeGraphError, UniquenessError, UnsupportedPredicateError, ValidationError, VersionConflictError, getErrorSuggestion, isConstraintError, isSystemError, isTypeGraphError, isUserRecoverable } from './chunk-WFMTAEEN.js';
|
|
7
|
-
import { MAX_PG_IDENTIFIER_LENGTH, DEFAULT_PAGINATION_LIMIT, getDialect, DEFAULT_STREAM_BATCH_SIZE, NODE_META_KEYS, EDGE_META_KEYS, SQLITE_PATH_DELIMITER, PG_ARRAY_START, PG_ARRAY_END, PG_PATH_ELEMENT_SEPARATOR, fnv1aBase36 } from './chunk-
|
|
8
|
-
export { fts5Strategy, tsvectorStrategy } from './chunk-
|
|
7
|
+
import { MAX_PG_IDENTIFIER_LENGTH, DEFAULT_PAGINATION_LIMIT, getDialect, DEFAULT_STREAM_BATCH_SIZE, NODE_META_KEYS, EDGE_META_KEYS, SQLITE_PATH_DELIMITER, PG_ARRAY_START, PG_ARRAY_END, PG_PATH_ELEMENT_SEPARATOR, fnv1aBase36 } from './chunk-753F33CV.js';
|
|
8
|
+
export { fts5Strategy, tsvectorStrategy } from './chunk-753F33CV.js';
|
|
9
9
|
import { jsonPointer, parseJsonPointer, createSchemaIntrospector, normalizeJsonPointer, joinJsonPointers, resolveFieldTypeInfoAtJsonPointer, getSearchableMetadata, DEFAULT_SEARCHABLE_LANGUAGE, getEmbeddingDimensions, isEmbeddingSchema } from './chunk-EYELZHKY.js';
|
|
10
10
|
export { DEFAULT_SEARCHABLE_LANGUAGE, MAX_JSON_POINTER_DEPTH, embedding, getEmbeddingDimensions, getSearchableMetadata, isEmbeddingSchema, isSearchableSchema, joinJsonPointers, jsonPointer, normalizeJsonPointer, parseJsonPointer, searchable } from './chunk-EYELZHKY.js';
|
|
11
11
|
import { z } from 'zod';
|
|
@@ -2107,6 +2107,7 @@ function buildStandardStartCte(input) {
|
|
|
2107
2107
|
const { ast, ctx, graphId, predicateIndex, requiredColumnsByAlias } = input;
|
|
2108
2108
|
const alias = ast.start.alias;
|
|
2109
2109
|
const kinds = ast.start.kinds;
|
|
2110
|
+
const cteMaterialization = ctx.dialect.capabilities.emitNotMaterializedHint ? sql`NOT MATERIALIZED ` : sql``;
|
|
2110
2111
|
const kindFilter = compileKindFilter(sql.raw("kind"), kinds);
|
|
2111
2112
|
const temporalFilter = input.temporalFilterPass.forAlias();
|
|
2112
2113
|
const cteContext = { ...ctx, cteColumnPrefix: "" };
|
|
@@ -2121,14 +2122,19 @@ function buildStandardStartCte(input) {
|
|
|
2121
2122
|
...predicateClauses
|
|
2122
2123
|
];
|
|
2123
2124
|
const effectiveRequiredColumns = requiredColumnsByAlias ? requiredColumnsByAlias.get(alias) ?? EMPTY_REQUIRED_COLUMNS : void 0;
|
|
2125
|
+
const limitClause = input.limitOffset === void 0 ? sql`` : input.limitOffset.offset === void 0 ? sql`
|
|
2126
|
+
LIMIT ${input.limitOffset.limit}
|
|
2127
|
+
` : sql`
|
|
2128
|
+
LIMIT ${input.limitOffset.limit} OFFSET ${input.limitOffset.offset}
|
|
2129
|
+
`;
|
|
2124
2130
|
return sql`
|
|
2125
|
-
cte_${sql.raw(alias)} AS (
|
|
2131
|
+
cte_${sql.raw(alias)} AS ${cteMaterialization}(
|
|
2126
2132
|
SELECT ${sql.join(
|
|
2127
2133
|
compileNodeSelectColumns(void 0, alias, effectiveRequiredColumns),
|
|
2128
2134
|
sql`, `
|
|
2129
2135
|
)}
|
|
2130
2136
|
FROM ${ctx.schema.nodesTable}
|
|
2131
|
-
WHERE ${sql.join(whereClauses, sql` AND `)}
|
|
2137
|
+
WHERE ${sql.join(whereClauses, sql` AND `)}${limitClause}
|
|
2132
2138
|
)
|
|
2133
2139
|
`;
|
|
2134
2140
|
}
|
|
@@ -2192,7 +2198,7 @@ function buildStandardTraversalCte(input) {
|
|
|
2192
2198
|
...compileEdgeSelectColumns("e", edgeAlias, requiredEdgeColumns),
|
|
2193
2199
|
...compileNodeSelectColumns("n", nodeAlias, requiredNodeColumns)
|
|
2194
2200
|
];
|
|
2195
|
-
const cteMaterialization = materializeCte ? sql`MATERIALIZED ` : sql``;
|
|
2201
|
+
const cteMaterialization = materializeCte ? sql`MATERIALIZED ` : ctx.dialect.capabilities.emitNotMaterializedHint ? sql`NOT MATERIALIZED ` : sql``;
|
|
2196
2202
|
function compileTraversalBranch(branch) {
|
|
2197
2203
|
const whereClauses = [
|
|
2198
2204
|
...baseWhereClauses,
|
|
@@ -5282,8 +5288,10 @@ function resolveCountAggregateFastPath(ast) {
|
|
|
5282
5288
|
if (groupField.alias !== ast.start.alias || !isIdFieldRef(groupField)) {
|
|
5283
5289
|
return void 0;
|
|
5284
5290
|
}
|
|
5285
|
-
let
|
|
5286
|
-
let
|
|
5291
|
+
let requiresNodeCount = false;
|
|
5292
|
+
let requiresNodeCountDistinct = false;
|
|
5293
|
+
let requiresEdgeCount = false;
|
|
5294
|
+
let requiresEdgeCountDistinct = false;
|
|
5287
5295
|
for (const projectedField of ast.projection.fields) {
|
|
5288
5296
|
const source = projectedField.source;
|
|
5289
5297
|
if (!isAggregateExpr(source)) {
|
|
@@ -5292,26 +5300,35 @@ function resolveCountAggregateFastPath(ast) {
|
|
|
5292
5300
|
}
|
|
5293
5301
|
continue;
|
|
5294
5302
|
}
|
|
5295
|
-
if (
|
|
5303
|
+
if (!isIdFieldRef(source.field)) {
|
|
5304
|
+
return void 0;
|
|
5305
|
+
}
|
|
5306
|
+
const isNodeTarget = source.field.alias === traversal.nodeAlias;
|
|
5307
|
+
const isEdgeTarget = source.field.alias === traversal.edgeAlias;
|
|
5308
|
+
if (!isNodeTarget && !isEdgeTarget) {
|
|
5296
5309
|
return void 0;
|
|
5297
5310
|
}
|
|
5298
5311
|
if (source.function === "count") {
|
|
5299
|
-
|
|
5312
|
+
if (isNodeTarget) requiresNodeCount = true;
|
|
5313
|
+
else requiresEdgeCount = true;
|
|
5300
5314
|
continue;
|
|
5301
5315
|
}
|
|
5302
5316
|
if (source.function === "countDistinct") {
|
|
5303
|
-
|
|
5317
|
+
if (isNodeTarget) requiresNodeCountDistinct = true;
|
|
5318
|
+
else requiresEdgeCountDistinct = true;
|
|
5304
5319
|
continue;
|
|
5305
5320
|
}
|
|
5306
5321
|
return void 0;
|
|
5307
5322
|
}
|
|
5308
|
-
if (!
|
|
5323
|
+
if (!requiresNodeCount && !requiresNodeCountDistinct && !requiresEdgeCount && !requiresEdgeCountDistinct) {
|
|
5309
5324
|
return void 0;
|
|
5310
5325
|
}
|
|
5311
5326
|
return {
|
|
5312
5327
|
traversal,
|
|
5313
|
-
|
|
5314
|
-
|
|
5328
|
+
requiresNodeCount,
|
|
5329
|
+
requiresNodeCountDistinct,
|
|
5330
|
+
requiresEdgeCount,
|
|
5331
|
+
requiresEdgeCountDistinct
|
|
5315
5332
|
};
|
|
5316
5333
|
}
|
|
5317
5334
|
function compileCountAggregateFastPath(ast, graphId, ctx, logicalPlan, requiredColumnsByAlias, predicateIndex, temporalFilterPass) {
|
|
@@ -5319,15 +5336,23 @@ function compileCountAggregateFastPath(ast, graphId, ctx, logicalPlan, requiredC
|
|
|
5319
5336
|
if (!plan) {
|
|
5320
5337
|
return void 0;
|
|
5321
5338
|
}
|
|
5322
|
-
const {
|
|
5339
|
+
const {
|
|
5340
|
+
traversal,
|
|
5341
|
+
requiresNodeCount,
|
|
5342
|
+
requiresNodeCountDistinct,
|
|
5343
|
+
requiresEdgeCount,
|
|
5344
|
+
requiresEdgeCountDistinct
|
|
5345
|
+
} = plan;
|
|
5323
5346
|
const { dialect } = ctx;
|
|
5324
5347
|
const startAlias = ast.start.alias;
|
|
5325
5348
|
const previousAlias = traversal.joinFromAlias;
|
|
5326
5349
|
const previousAliasIdColumn = `${previousAlias}_id`;
|
|
5327
5350
|
const previousAliasKindColumn = `${previousAlias}_kind`;
|
|
5328
5351
|
const countCteAlias = `cte_${traversal.nodeAlias}_counts`;
|
|
5329
|
-
const
|
|
5330
|
-
const
|
|
5352
|
+
const nodeCountColumn = `${traversal.nodeAlias}_count`;
|
|
5353
|
+
const nodeCountDistinctColumn = `${traversal.nodeAlias}_count_distinct`;
|
|
5354
|
+
const edgeCountColumn = `${traversal.edgeAlias}_count`;
|
|
5355
|
+
const edgeCountDistinctColumn = `${traversal.edgeAlias}_count_distinct`;
|
|
5331
5356
|
const previousNodeKinds = getNodeKindsForAlias(ast, traversal.joinFromAlias);
|
|
5332
5357
|
const edgeKinds = [...new Set(traversal.edgeKinds)];
|
|
5333
5358
|
const nodeKinds = traversal.nodeKinds;
|
|
@@ -5353,34 +5378,68 @@ function compileCountAggregateFastPath(ast, graphId, ctx, logicalPlan, requiredC
|
|
|
5353
5378
|
const targetField = traversal.direction === "out" ? "to_id" : "from_id";
|
|
5354
5379
|
const joinKindField = traversal.direction === "out" ? "from_kind" : "to_kind";
|
|
5355
5380
|
const targetKindField = traversal.direction === "out" ? "to_kind" : "from_kind";
|
|
5381
|
+
const hasNodePredicates = nodePredicateClauses.length > 0;
|
|
5382
|
+
const requiresNodeJoin = requiresNodeCount || requiresNodeCountDistinct || hasNodePredicates;
|
|
5383
|
+
const useInnerJoin = hasNodePredicates;
|
|
5356
5384
|
const whereClauses = [
|
|
5357
5385
|
sql`e.graph_id = ${graphId}`,
|
|
5358
5386
|
compileKindFilter(sql.raw("e.kind"), edgeKinds),
|
|
5359
5387
|
compileKindFilter(sql.raw(`e.${joinKindField}`), previousNodeKinds),
|
|
5360
5388
|
compileKindFilter(sql.raw(`e.${targetKindField}`), nodeKinds),
|
|
5361
|
-
compileKindFilter(sql.raw("n.kind"), nodeKinds),
|
|
5362
5389
|
edgeTemporalFilter,
|
|
5363
|
-
|
|
5364
|
-
|
|
5365
|
-
...
|
|
5390
|
+
...edgePredicateClauses,
|
|
5391
|
+
// INNER JOIN mode: node-side filters in WHERE constrain every aggregate.
|
|
5392
|
+
...requiresNodeJoin && useInnerJoin ? [
|
|
5393
|
+
compileKindFilter(sql.raw("n.kind"), nodeKinds),
|
|
5394
|
+
nodeTemporalFilter,
|
|
5395
|
+
...nodePredicateClauses
|
|
5396
|
+
] : []
|
|
5366
5397
|
];
|
|
5398
|
+
const nodeJoinOnClauses = requiresNodeJoin ? useInnerJoin ? (
|
|
5399
|
+
// INNER JOIN: only the key conditions; filters live in WHERE.
|
|
5400
|
+
[
|
|
5401
|
+
sql`n.graph_id = e.graph_id`,
|
|
5402
|
+
sql`n.id = e.${sql.raw(targetField)}`,
|
|
5403
|
+
sql`n.kind = e.${sql.raw(targetKindField)}`
|
|
5404
|
+
]
|
|
5405
|
+
) : [
|
|
5406
|
+
sql`n.graph_id = e.graph_id`,
|
|
5407
|
+
sql`n.id = e.${sql.raw(targetField)}`,
|
|
5408
|
+
sql`n.kind = e.${sql.raw(targetKindField)}`,
|
|
5409
|
+
compileKindFilter(sql.raw("n.kind"), nodeKinds),
|
|
5410
|
+
nodeTemporalFilter
|
|
5411
|
+
] : [];
|
|
5367
5412
|
const aggregateColumns = [];
|
|
5368
|
-
if (
|
|
5369
|
-
aggregateColumns.push(sql`COUNT(n.id) AS ${sql.raw(
|
|
5413
|
+
if (requiresNodeCount) {
|
|
5414
|
+
aggregateColumns.push(sql`COUNT(n.id) AS ${sql.raw(nodeCountColumn)}`);
|
|
5415
|
+
}
|
|
5416
|
+
if (requiresNodeCountDistinct) {
|
|
5417
|
+
aggregateColumns.push(
|
|
5418
|
+
sql`COUNT(DISTINCT n.id) AS ${sql.raw(nodeCountDistinctColumn)}`
|
|
5419
|
+
);
|
|
5420
|
+
}
|
|
5421
|
+
if (requiresEdgeCount) {
|
|
5422
|
+
aggregateColumns.push(sql`COUNT(e.id) AS ${sql.raw(edgeCountColumn)}`);
|
|
5370
5423
|
}
|
|
5371
|
-
if (
|
|
5424
|
+
if (requiresEdgeCountDistinct) {
|
|
5372
5425
|
aggregateColumns.push(
|
|
5373
|
-
sql`COUNT(DISTINCT
|
|
5426
|
+
sql`COUNT(DISTINCT e.id) AS ${sql.raw(edgeCountDistinctColumn)}`
|
|
5374
5427
|
);
|
|
5375
5428
|
}
|
|
5429
|
+
const startCteLimit = traversal.optional && ast.orderBy === void 0 && ast.limit !== void 0 ? { limit: ast.limit, offset: ast.offset } : void 0;
|
|
5376
5430
|
const startCte = buildStandardStartCte({
|
|
5377
5431
|
ast,
|
|
5378
5432
|
ctx,
|
|
5379
5433
|
graphId,
|
|
5380
5434
|
predicateIndex,
|
|
5381
5435
|
requiredColumnsByAlias,
|
|
5382
|
-
temporalFilterPass
|
|
5436
|
+
temporalFilterPass,
|
|
5437
|
+
...startCteLimit === void 0 ? {} : { limitOffset: startCteLimit }
|
|
5383
5438
|
});
|
|
5439
|
+
const targetNodeJoinKeyword = useInnerJoin ? "JOIN" : "LEFT JOIN";
|
|
5440
|
+
const targetNodeJoin = requiresNodeJoin ? sql`
|
|
5441
|
+
${sql.raw(targetNodeJoinKeyword)} ${ctx.schema.nodesTable} n ON ${sql.join(nodeJoinOnClauses, sql` AND `)}
|
|
5442
|
+
` : sql``;
|
|
5384
5443
|
const countCte = sql`
|
|
5385
5444
|
${sql.raw(countCteAlias)} AS (
|
|
5386
5445
|
SELECT
|
|
@@ -5389,16 +5448,20 @@ function compileCountAggregateFastPath(ast, graphId, ctx, logicalPlan, requiredC
|
|
|
5389
5448
|
${sql.join(aggregateColumns, sql`, `)}
|
|
5390
5449
|
FROM cte_${sql.raw(previousAlias)}
|
|
5391
5450
|
JOIN ${ctx.schema.edgesTable} e ON cte_${sql.raw(previousAlias)}.${sql.raw(previousAliasIdColumn)} = e.${sql.raw(joinField)}
|
|
5392
|
-
AND cte_${sql.raw(previousAlias)}.${sql.raw(previousAliasKindColumn)} = e.${sql.raw(joinKindField)}
|
|
5393
|
-
JOIN ${ctx.schema.nodesTable} n ON n.graph_id = e.graph_id
|
|
5394
|
-
AND n.id = e.${sql.raw(targetField)}
|
|
5395
|
-
AND n.kind = e.${sql.raw(targetKindField)}
|
|
5451
|
+
AND cte_${sql.raw(previousAlias)}.${sql.raw(previousAliasKindColumn)} = e.${sql.raw(joinKindField)}${targetNodeJoin}
|
|
5396
5452
|
WHERE ${sql.join(whereClauses, sql` AND `)}
|
|
5397
5453
|
GROUP BY
|
|
5398
5454
|
cte_${sql.raw(previousAlias)}.${sql.raw(previousAliasIdColumn)},
|
|
5399
5455
|
cte_${sql.raw(previousAlias)}.${sql.raw(previousAliasKindColumn)}
|
|
5400
5456
|
)
|
|
5401
5457
|
`;
|
|
5458
|
+
function resolveCountColumn(source) {
|
|
5459
|
+
const isEdge = source.field.alias === traversal.edgeAlias;
|
|
5460
|
+
if (source.function === "countDistinct") {
|
|
5461
|
+
return isEdge ? edgeCountDistinctColumn : nodeCountDistinctColumn;
|
|
5462
|
+
}
|
|
5463
|
+
return isEdge ? edgeCountColumn : nodeCountColumn;
|
|
5464
|
+
}
|
|
5402
5465
|
const projection = sql.join(
|
|
5403
5466
|
ast.projection.fields.map((projectedField) => {
|
|
5404
5467
|
const source = projectedField.source;
|
|
@@ -5411,7 +5474,7 @@ function compileCountAggregateFastPath(ast, graphId, ctx, logicalPlan, requiredC
|
|
|
5411
5474
|
);
|
|
5412
5475
|
return sql`${value} AS ${quoteIdentifier2(projectedField.outputName)}`;
|
|
5413
5476
|
}
|
|
5414
|
-
const projectedCountColumn = source
|
|
5477
|
+
const projectedCountColumn = resolveCountColumn(source);
|
|
5415
5478
|
const countValue = sql`${sql.raw(countCteAlias)}.${sql.raw(projectedCountColumn)}`;
|
|
5416
5479
|
const aggregateValue = traversal.optional ? sql`COALESCE(${countValue}, 0)` : countValue;
|
|
5417
5480
|
return sql`${aggregateValue} AS ${quoteIdentifier2(projectedField.outputName)}`;
|
|
@@ -5426,19 +5489,29 @@ function compileCountAggregateFastPath(ast, graphId, ctx, logicalPlan, requiredC
|
|
|
5426
5489
|
AND ${sql.raw(countCteAlias)}.${sql.raw(previousAliasKindColumn)} = cte_${sql.raw(previousAlias)}.${sql.raw(previousAliasKindColumn)}
|
|
5427
5490
|
`;
|
|
5428
5491
|
const orderBy = buildStandardOrderBy({ ast, dialect });
|
|
5429
|
-
const
|
|
5430
|
-
|
|
5431
|
-
offset: ast.offset
|
|
5432
|
-
});
|
|
5492
|
+
const emittedLogicalPlan = startCteLimit === void 0 ? logicalPlan : stripLimitOffsetFromPlan(logicalPlan);
|
|
5493
|
+
const limitOffset = startCteLimit === void 0 ? buildLimitOffsetClause({ limit: ast.limit, offset: ast.offset }) : void 0;
|
|
5433
5494
|
return emitStandardQuerySql({
|
|
5434
5495
|
ctes: [startCte, countCte],
|
|
5435
5496
|
fromClause,
|
|
5436
5497
|
...orderBy === void 0 ? {} : { orderBy },
|
|
5437
5498
|
...limitOffset === void 0 ? {} : { limitOffset },
|
|
5438
|
-
logicalPlan,
|
|
5499
|
+
logicalPlan: emittedLogicalPlan,
|
|
5439
5500
|
projection
|
|
5440
5501
|
});
|
|
5441
5502
|
}
|
|
5503
|
+
function stripLimitOffsetFromPlan(plan) {
|
|
5504
|
+
return { ...plan, root: stripLimitOffsetFromPlanNode(plan.root) };
|
|
5505
|
+
}
|
|
5506
|
+
function stripLimitOffsetFromPlanNode(node) {
|
|
5507
|
+
if (node.op === "limit_offset") {
|
|
5508
|
+
return stripLimitOffsetFromPlanNode(node.input);
|
|
5509
|
+
}
|
|
5510
|
+
if ("input" in node) {
|
|
5511
|
+
return { ...node, input: stripLimitOffsetFromPlanNode(node.input) };
|
|
5512
|
+
}
|
|
5513
|
+
return node;
|
|
5514
|
+
}
|
|
5442
5515
|
var STANDARD_QUERY_STRATEGY_HANDLERS = {
|
|
5443
5516
|
cte_project: compileStandardQueryWithCteStrategy
|
|
5444
5517
|
};
|
|
@@ -9363,6 +9436,12 @@ function countDistinct(alias, field2) {
|
|
|
9363
9436
|
}
|
|
9364
9437
|
};
|
|
9365
9438
|
}
|
|
9439
|
+
function countEdges(edgeAlias) {
|
|
9440
|
+
return count(edgeAlias);
|
|
9441
|
+
}
|
|
9442
|
+
function countDistinctEdges(edgeAlias) {
|
|
9443
|
+
return countDistinct(edgeAlias);
|
|
9444
|
+
}
|
|
9366
9445
|
function sum(alias, field2) {
|
|
9367
9446
|
return {
|
|
9368
9447
|
__type: "aggregate",
|
|
@@ -13676,6 +13755,6 @@ async function createStoreWithSchema(graph, backend, options) {
|
|
|
13676
13755
|
return [store, result];
|
|
13677
13756
|
}
|
|
13678
13757
|
|
|
13679
|
-
export { DEFAULT_SQL_SCHEMA, ExecutableAggregateQuery, ExecutableQuery, MAX_EXPLICIT_RECURSIVE_DEPTH, MAX_RECURSIVE_DEPTH, PreparedQuery, QueryBuilder, StoreSearch, UnionableQuery, avg, broader, composeFragments, core, count, countDistinct, createExternalRef, createFragment, createQueryBuilder, createSqlSchema, createStore, createStoreWithSchema, defineEdge, defineNode, defineSubgraphProject, differentFrom, disjointWith, equivalentTo, exists, externalRef, field, fieldRef, generateId, getExternalRefTable, hasPart, having, havingEq, havingGt, havingGte, havingLt, havingLte, implies, inSubquery, inverseOf, isExternalRefSchema, isParameterRef, limitFragment, max, metaEdge, min, narrower, notExists, notInSubquery, offsetFragment, orderByFragment, param, partOf, relatedTo, sameAs, subClassOf, sum };
|
|
13758
|
+
export { DEFAULT_SQL_SCHEMA, ExecutableAggregateQuery, ExecutableQuery, MAX_EXPLICIT_RECURSIVE_DEPTH, MAX_RECURSIVE_DEPTH, PreparedQuery, QueryBuilder, StoreSearch, UnionableQuery, avg, broader, composeFragments, core, count, countDistinct, countDistinctEdges, countEdges, createExternalRef, createFragment, createQueryBuilder, createSqlSchema, createStore, createStoreWithSchema, defineEdge, defineNode, defineSubgraphProject, differentFrom, disjointWith, equivalentTo, exists, externalRef, field, fieldRef, generateId, getExternalRefTable, hasPart, having, havingEq, havingGt, havingGte, havingLt, havingLte, implies, inSubquery, inverseOf, isExternalRefSchema, isParameterRef, limitFragment, max, metaEdge, min, narrower, notExists, notInSubquery, offsetFragment, orderByFragment, param, partOf, relatedTo, sameAs, subClassOf, sum };
|
|
13680
13759
|
//# sourceMappingURL=index.js.map
|
|
13681
13760
|
//# sourceMappingURL=index.js.map
|