@undefineds.co/xpod 0.3.54 → 0.3.55

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.
@@ -132,6 +132,7 @@ export declare class RdfSparqlAdapter {
132
132
  private havingAggregateVariableOrUndefined;
133
133
  private assertGroupProjection;
134
134
  private compileOrder;
135
+ private addSolutionBind;
135
136
  private compileOrderExpression;
136
137
  private compileFilter;
137
138
  private compileOrFilter;
@@ -1215,13 +1215,14 @@ class RdfSparqlAdapter {
1215
1215
  const alias = variable.variable.value;
1216
1216
  if (variables.includes(alias)
1217
1217
  || visibleVariables.includes(alias)
1218
- || (rdfQuery.binds ?? []).some((bind) => bind.variable === alias)) {
1218
+ || (rdfQuery.binds ?? []).some((bind) => bind.variable === alias)
1219
+ || (rdfQuery.postOptionalBinds ?? []).some((bind) => bind.variable === alias)) {
1219
1220
  throw new UnsupportedSparqlQueryError('SELECT expression alias is already bound locally');
1220
1221
  }
1221
- state.addBind({
1222
+ this.addSolutionBind(state, {
1222
1223
  variable: alias,
1223
1224
  expression: this.compileSelectProjectionExpression(variable.expression, state.basePath),
1224
- }, false);
1225
+ });
1225
1226
  variables.push(alias);
1226
1227
  continue;
1227
1228
  }
@@ -1452,16 +1453,26 @@ class RdfSparqlAdapter {
1452
1453
  };
1453
1454
  }
1454
1455
  const orderVariable = state.nextOrderVariable(index);
1455
- state.addBind({
1456
+ this.addSolutionBind(state, {
1456
1457
  variable: orderVariable,
1457
1458
  expression: this.compileOrderExpression(entry.expression, state.basePath),
1458
- }, false);
1459
+ });
1459
1460
  return {
1460
1461
  variable: orderVariable,
1461
1462
  direction: entry.descending ? 'desc' : 'asc',
1462
1463
  };
1463
1464
  });
1464
1465
  }
1466
+ addSolutionBind(state, bind) {
1467
+ const optionalVariables = new Set(variablesBoundByNestedOptionalGroups(state.query.optional ?? []));
1468
+ const dependsOnOptionalVariable = variablesInBindExpression(bind.expression)
1469
+ .some((variableName) => optionalVariables.has(variableName));
1470
+ if (dependsOnOptionalVariable) {
1471
+ state.addPostOptionalBind(bind);
1472
+ return;
1473
+ }
1474
+ state.addBind(bind, false);
1475
+ }
1465
1476
  compileOrderExpression(expression, basePath) {
1466
1477
  return this.compileBindLikeExpression(expression, basePath, 'ORDER BY');
1467
1478
  }
@@ -2222,6 +2233,10 @@ class CompileState {
2222
2233
  this.query.binds ??= [];
2223
2234
  this.query.binds.push(bind);
2224
2235
  }
2236
+ addPostOptionalBind(bind) {
2237
+ this.query.postOptionalBinds ??= [];
2238
+ this.query.postOptionalBinds.push(bind);
2239
+ }
2225
2240
  addOptionalUnion(branches) {
2226
2241
  this.currentOptionalFrame().unions.push({ branches });
2227
2242
  }
@@ -2317,6 +2332,18 @@ class CompileState {
2317
2332
  for (const rawOptionalGroup of this.query.optional ?? []) {
2318
2333
  assertOptionalBindVariablesSafe(rawOptionalGroup, bound);
2319
2334
  }
2335
+ const postOptionalBound = new Set(bound);
2336
+ for (const variableName of variablesBoundByNestedOptionalGroups(this.query.optional ?? [])) {
2337
+ postOptionalBound.add(variableName);
2338
+ }
2339
+ for (const bind of this.query.postOptionalBinds ?? []) {
2340
+ for (const dependency of variablesInBindExpression(bind.expression)) {
2341
+ if (!postOptionalBound.has(dependency)) {
2342
+ throw new UnsupportedSparqlQueryError('BIND dependency must be bound before use locally');
2343
+ }
2344
+ }
2345
+ postOptionalBound.add(bind.variable);
2346
+ }
2320
2347
  }
2321
2348
  assertDependentGroupsShareRequiredVariables() {
2322
2349
  if (this.skipMinusSharedVariableCheck) {