@lde/pipeline 0.39.0 → 0.39.1
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/sparql/values.d.ts
CHANGED
|
@@ -10,7 +10,10 @@ export declare function findSubSelect(patterns: Pattern[]): QuerySelect | undefi
|
|
|
10
10
|
*
|
|
11
11
|
* Each row's keys become SPARQL variables; NamedNode values become IRIs in the
|
|
12
12
|
* VALUES block. The VALUES clause is injected into the innermost subquery so
|
|
13
|
-
* that SPARQL engines can constrain scans early.
|
|
13
|
+
* that SPARQL engines can constrain scans early. When that WHERE clause is a
|
|
14
|
+
* single UNION whose branches all bind the VALUES variables in a required
|
|
15
|
+
* triple pattern, the VALUES goes into each branch instead: engines such as
|
|
16
|
+
* QLever plan and evaluate each branch without the outer VALUES otherwise.
|
|
14
17
|
*
|
|
15
18
|
* The caller owns parsing and stringifying; this function operates on the AST.
|
|
16
19
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"values.d.ts","sourceRoot":"","sources":["../../src/sparql/values.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,OAAO,
|
|
1
|
+
{"version":3,"file":"values.d.ts","sourceRoot":"","sources":["../../src/sparql/values.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,OAAO,EAIZ,KAAK,cAAc,EACnB,KAAK,WAAW,EAEjB,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAIpD;;;GAGG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,WAAW,GAAG,SAAS,CAW1E;AA0GD;;;;;;;;;;;GAWG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,cAAc,EACrB,QAAQ,EAAE,gBAAgB,EAAE,GAC3B,cAAc,CAoBhB"}
|
package/dist/sparql/values.js
CHANGED
|
@@ -47,8 +47,9 @@ function mapSubSelect(patterns, replacer) {
|
|
|
47
47
|
* clause into the innermost WHERE clause. This ensures that SPARQL engines
|
|
48
48
|
* constrain scans at the deepest level rather than only at the outer scope.
|
|
49
49
|
*
|
|
50
|
-
* For flat queries (no SubSelect), the base case injects directly
|
|
51
|
-
*
|
|
50
|
+
* For flat queries (no SubSelect), the base case injects directly: in front of
|
|
51
|
+
* the WHERE clause, or into each branch when it is a single UNION whose branches
|
|
52
|
+
* all qualify (see {@link bindsAllVariables}).
|
|
52
53
|
*/
|
|
53
54
|
function injectIntoInnermost(where, valuesPattern) {
|
|
54
55
|
const mapped = mapSubSelect(where.patterns, (subSelect) => ({
|
|
@@ -56,17 +57,54 @@ function injectIntoInnermost(where, valuesPattern) {
|
|
|
56
57
|
where: injectIntoInnermost(subSelect.where, valuesPattern),
|
|
57
58
|
}));
|
|
58
59
|
if (!mapped) {
|
|
59
|
-
// Base case: no SubSelect
|
|
60
|
+
// Base case: no SubSelect – inject here, into each UNION branch if safe.
|
|
61
|
+
const branches = where.patterns.length === 1 && F.isPatternUnion(where.patterns[0])
|
|
62
|
+
? where.patterns[0].patterns
|
|
63
|
+
: [];
|
|
64
|
+
if (branches.length > 0 &&
|
|
65
|
+
branches.every((branch) => bindsAllVariables(branch, valuesPattern))) {
|
|
66
|
+
return F.patternGroup([
|
|
67
|
+
F.patternUnion(branches.map((branch) => F.patternGroup([valuesPattern, ...branch.patterns], F.gen())), F.gen()),
|
|
68
|
+
], F.gen());
|
|
69
|
+
}
|
|
60
70
|
return F.patternGroup([valuesPattern, ...where.patterns], F.gen());
|
|
61
71
|
}
|
|
62
72
|
return F.patternGroup(mapped, F.gen());
|
|
63
73
|
}
|
|
74
|
+
/**
|
|
75
|
+
* Whether a UNION branch binds every VALUES variable in a triple pattern of a
|
|
76
|
+
* top-level BGP that precedes the branch’s first OPTIONAL, MINUS, BIND or other
|
|
77
|
+
* non-FILTER pattern. Those apply to the solutions before them, so only then
|
|
78
|
+
* does joining the VALUES first in the branch return the same solutions as
|
|
79
|
+
* joining it outside the UNION. FILTERs apply to the whole group, wherever they are.
|
|
80
|
+
*/
|
|
81
|
+
function bindsAllVariables(branch, valuesPattern) {
|
|
82
|
+
const bound = new Set();
|
|
83
|
+
for (const pattern of branch.patterns) {
|
|
84
|
+
if (pattern.subType === 'filter')
|
|
85
|
+
continue;
|
|
86
|
+
if (!F.isPatternBgp(pattern))
|
|
87
|
+
break;
|
|
88
|
+
for (const triple of pattern.triples) {
|
|
89
|
+
if (triple.type !== 'triple')
|
|
90
|
+
continue;
|
|
91
|
+
for (const term of [triple.subject, triple.predicate, triple.object]) {
|
|
92
|
+
if (F.isTermVariable(term))
|
|
93
|
+
bound.add(term.value);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return valuesPattern.variables.every((variable) => bound.has(variable.value));
|
|
98
|
+
}
|
|
64
99
|
/**
|
|
65
100
|
* Inject a VALUES clause into a parsed CONSTRUCT query for the given binding rows.
|
|
66
101
|
*
|
|
67
102
|
* Each row's keys become SPARQL variables; NamedNode values become IRIs in the
|
|
68
103
|
* VALUES block. The VALUES clause is injected into the innermost subquery so
|
|
69
|
-
* that SPARQL engines can constrain scans early.
|
|
104
|
+
* that SPARQL engines can constrain scans early. When that WHERE clause is a
|
|
105
|
+
* single UNION whose branches all bind the VALUES variables in a required
|
|
106
|
+
* triple pattern, the VALUES goes into each branch instead: engines such as
|
|
107
|
+
* QLever plan and evaluate each branch without the outer VALUES otherwise.
|
|
70
108
|
*
|
|
71
109
|
* The caller owns parsing and stringifying; this function operates on the AST.
|
|
72
110
|
*/
|