simple-graph-query 2.7.0 → 2.7.2
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.
|
@@ -48626,10 +48626,19 @@ class ForgeExprEvaluator extends AbstractParseTreeVisitor_1.AbstractParseTreeVis
|
|
|
48626
48626
|
// Convert numeric and boolean strings to their actual types
|
|
48627
48627
|
relationAtoms = relationAtoms.map((tuple) => tuple.map((value) => this.isConvertibleToNumber(value) ? Number(value) : value));
|
|
48628
48628
|
relationAtoms = relationAtoms.map((tuple) => tuple.map((value) => this.isConvertibleToBoolean(value) ? this.convertToBoolean(value) : value));
|
|
48629
|
-
|
|
48630
|
-
//
|
|
48629
|
+
// Relation NAMES are not unique — only the qualified id (`Sig<:label`) is.
|
|
48630
|
+
// e.g. `open util/ordering[A]` and `open util/ordering[B]` both expose a field
|
|
48631
|
+
// named `Next` (`A/Ord<:Next` and `B/Ord<:Next`). A bare-name reference must
|
|
48632
|
+
// resolve to the UNION of every relation sharing that name; keying by name and
|
|
48633
|
+
// overwriting silently erases all but the last. https://github.com/sidprasad/simple-graph-query/issues/55
|
|
48634
|
+
const existing = this.relationCache.get(relation.name);
|
|
48635
|
+
this.relationCache.set(relation.name, existing ? existing.concat(relationAtoms) : relationAtoms);
|
|
48636
|
+
}
|
|
48637
|
+
// Build first-element indexes from the merged (union'd) tuples, so an index
|
|
48638
|
+
// never reflects only a subset of a name's relations.
|
|
48639
|
+
for (const [name, tuples] of this.relationCache.entries()) {
|
|
48631
48640
|
const relationIndex = new Map();
|
|
48632
|
-
for (const tuple of
|
|
48641
|
+
for (const tuple of tuples) {
|
|
48633
48642
|
if (tuple.length > 0) {
|
|
48634
48643
|
const key = tuple[0];
|
|
48635
48644
|
if (!relationIndex.has(key)) {
|
|
@@ -48638,7 +48647,7 @@ class ForgeExprEvaluator extends AbstractParseTreeVisitor_1.AbstractParseTreeVis
|
|
|
48638
48647
|
relationIndex.get(key).push(tuple);
|
|
48639
48648
|
}
|
|
48640
48649
|
}
|
|
48641
|
-
this.relationIndexCache.set(
|
|
48650
|
+
this.relationIndexCache.set(name, relationIndex);
|
|
48642
48651
|
}
|
|
48643
48652
|
}
|
|
48644
48653
|
//helper function
|
|
@@ -50821,10 +50830,17 @@ const UNKNOWN = { kind: "unknown" };
|
|
|
50821
50830
|
class SchemaInfo {
|
|
50822
50831
|
constructor(schema) {
|
|
50823
50832
|
this.typesById = new Map(schema.getTypes().map((t) => [t.id, t]));
|
|
50824
|
-
this.relationsByName = new Map(
|
|
50833
|
+
this.relationsByName = new Map();
|
|
50834
|
+
for (const r of schema.getRelations()) {
|
|
50835
|
+
const existing = this.relationsByName.get(r.name);
|
|
50836
|
+
if (existing)
|
|
50837
|
+
existing.push(r);
|
|
50838
|
+
else
|
|
50839
|
+
this.relationsByName.set(r.name, [r]);
|
|
50840
|
+
}
|
|
50825
50841
|
}
|
|
50826
50842
|
getType(id) { return this.typesById.get(id); }
|
|
50827
|
-
|
|
50843
|
+
getRelations(name) { return this.relationsByName.get(name) ?? []; }
|
|
50828
50844
|
// A ⊆ B when B is in A's lineage. `IType.types` is the lineage in ascending
|
|
50829
50845
|
// order, conventionally starting with the type itself.
|
|
50830
50846
|
isSubtypeOf(a, b) {
|
|
@@ -50965,7 +50981,7 @@ class ForgeExprStaticAnalyzer extends AbstractParseTreeVisitor_1.AbstractParseTr
|
|
|
50965
50981
|
if (!this.schema)
|
|
50966
50982
|
return undefined;
|
|
50967
50983
|
for (const name of names) {
|
|
50968
|
-
if (this.schema.getType(name) || this.schema.
|
|
50984
|
+
if (this.schema.getType(name) || this.schema.getRelations(name).length > 0) {
|
|
50969
50985
|
return {
|
|
50970
50986
|
kind: "ill-typed",
|
|
50971
50987
|
reason: `cannot bind variable named '${name}': it is a reserved schema ` +
|
|
@@ -51746,11 +51762,26 @@ class ForgeExprStaticAnalyzer extends AbstractParseTreeVisitor_1.AbstractParseTr
|
|
|
51746
51762
|
const t = this.schema.getType(id);
|
|
51747
51763
|
if (t)
|
|
51748
51764
|
return { kind: "typed", arity: 1, columnTypes: [t.id] };
|
|
51749
|
-
const
|
|
51750
|
-
if (
|
|
51751
|
-
const cols =
|
|
51765
|
+
const rels = this.schema.getRelations(id);
|
|
51766
|
+
if (rels.length === 1) {
|
|
51767
|
+
const cols = rels[0].types;
|
|
51752
51768
|
return { kind: "typed", arity: cols.length, columnTypes: cols };
|
|
51753
51769
|
}
|
|
51770
|
+
if (rels.length > 1) {
|
|
51771
|
+
// A bare name denotes the union of every relation sharing it. Different
|
|
51772
|
+
// arities have no single typing, so stay UNKNOWN. When arities agree,
|
|
51773
|
+
// keep the arity; keep per-column types only where every relation agrees
|
|
51774
|
+
// (otherwise omit, so downstream disjointness checks soundly skip rather
|
|
51775
|
+
// than fire on a widened column).
|
|
51776
|
+
const arity = rels[0].types.length;
|
|
51777
|
+
if (rels.every((r) => r.types.length === arity)) {
|
|
51778
|
+
const cols = rels[0].types.map((col, i) => rels.every((r) => r.types[i] === col) ? col : undefined);
|
|
51779
|
+
const allKnown = cols.every((c) => c !== undefined);
|
|
51780
|
+
return allKnown
|
|
51781
|
+
? { kind: "typed", arity, columnTypes: cols }
|
|
51782
|
+
: { kind: "typed", arity };
|
|
51783
|
+
}
|
|
51784
|
+
}
|
|
51754
51785
|
}
|
|
51755
51786
|
return UNKNOWN;
|
|
51756
51787
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "simple-graph-query",
|
|
3
|
-
"version": "2.7.
|
|
3
|
+
"version": "2.7.2",
|
|
4
4
|
"description": "TypeScript evaluator for Forge expressions with browser-compatible UMD bundle",
|
|
5
5
|
"main": "dist/simple-graph-query.bundle.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -33,10 +33,15 @@
|
|
|
33
33
|
"prepublishOnly": "npm run build:full",
|
|
34
34
|
"serve": "python3 -m http.server 8080",
|
|
35
35
|
"test": "jest",
|
|
36
|
-
"antlr4ts": "cd src/forge-antlr && antlr4ts -visitor ForgeLexer.g4 Forge.g4 && cd ../.."
|
|
36
|
+
"antlr4ts": "cd src/forge-antlr && antlr4ts -visitor ForgeLexer.g4 Forge.g4 && cd ../..",
|
|
37
|
+
"release:tag": "git diff-index --quiet HEAD -- || (echo 'Working tree is dirty, commit first' && exit 1) && git tag v$npm_package_version && git push origin v$npm_package_version"
|
|
37
38
|
},
|
|
38
39
|
"author": "Siddhartha Prasad",
|
|
39
40
|
"license": "MIT",
|
|
41
|
+
"repository": {
|
|
42
|
+
"type": "git",
|
|
43
|
+
"url": "git+https://github.com/sidprasad/simple-graph-query.git"
|
|
44
|
+
},
|
|
40
45
|
"devDependencies": {
|
|
41
46
|
"@types/jest": "^29.5.14",
|
|
42
47
|
"antlr4ts-cli": "^0.5.0-alpha.4",
|