@comunica/actor-optimize-query-operation-filter-pushdown 4.2.0 → 4.4.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.
@@ -208,10 +208,6 @@
208
208
  "@id": "caoqofp:components/ActorOptimizeQueryOperationFilterPushdown.jsonld#ActorOptimizeQueryOperationFilterPushdown__member_getSources",
209
209
  "memberFieldName": "getSources"
210
210
  },
211
- {
212
- "@id": "caoqofp:components/ActorOptimizeQueryOperationFilterPushdown.jsonld#ActorOptimizeQueryOperationFilterPushdown__member_getExpressionVariables",
213
- "memberFieldName": "getExpressionVariables"
214
- },
215
211
  {
216
212
  "@id": "caoqofp:components/ActorOptimizeQueryOperationFilterPushdown.jsonld#ActorOptimizeQueryOperationFilterPushdown__member_getOverlappingOperations",
217
213
  "memberFieldName": "getOverlappingOperations"
@@ -21,23 +21,22 @@ export declare class ActorOptimizeQueryOperationFilterPushdown extends ActorOpti
21
21
  * Check if the given filter operation must be attempted to push down, based on the following criteria:
22
22
  * - Always push down if aggressive mode is enabled
23
23
  * - Push down if the filter is extremely selective
24
+ * - Don't push down extension functions comunica support, but a source does not
24
25
  * - Push down if federated and at least one accepts the filter
25
26
  * @param operation The filter operation
26
27
  * @param sources The query sources in the operation
27
28
  * @param sourceShapes A mapping of sources to selector shapes.
29
+ * @param extensionFunctions The extension functions comunica supports.
30
+ * @param extensionFunctionsAlwaysPushdown If extension functions must always be pushed down to sources that support
31
+ * expressions, even if those sources to not explicitly declare support for
32
+ * these extension functions.
28
33
  */
29
- shouldAttemptPushDown(operation: Algebra.Filter, sources: IQuerySourceWrapper[], sourceShapes: Map<IQuerySourceWrapper, FragmentSelectorShape>): boolean;
34
+ shouldAttemptPushDown(operation: Algebra.Filter, sources: IQuerySourceWrapper[], sourceShapes: Map<IQuerySourceWrapper, FragmentSelectorShape>, extensionFunctions?: Record<string, any>, extensionFunctionsAlwaysPushdown?: boolean): boolean;
30
35
  /**
31
36
  * Collected all sources that are defined within the given operation of children recursively.
32
37
  * @param operation An operation.
33
38
  */
34
39
  getSources(operation: Algebra.Operation): IQuerySourceWrapper[];
35
- /**
36
- * Get all variables inside the given expression.
37
- * @param expression An expression.
38
- * @return An array of variables, or undefined if the expression is unsupported for pushdown.
39
- */
40
- getExpressionVariables(expression: Algebra.Expression): RDF.Variable[];
41
40
  protected getOverlappingOperations(operation: Algebra.Operation, expressionVariables: RDF.Variable[]): {
42
41
  fullyOverlapping: Algebra.Operation[];
43
42
  partiallyOverlapping: Algebra.Operation[];
@@ -57,7 +57,10 @@ class ActorOptimizeQueryOperationFilterPushdown extends bus_optimize_query_opera
57
57
  operation = sparqlalgebrajs_1.Util.mapOperation(operation, {
58
58
  filter(op, factory) {
59
59
  // Check if the filter must be pushed down
60
- if (!self.shouldAttemptPushDown(op, sources, sourceShapes)) {
60
+ const extensionFunctions = action.context.get(context_entries_1.KeysInitQuery.extensionFunctions);
61
+ const extensionFunctionsAlwaysPushdown = action.context.get(context_entries_1.KeysInitQuery.extensionFunctionsAlwaysPushdown);
62
+ if (!self
63
+ .shouldAttemptPushDown(op, sources, sourceShapes, extensionFunctions, extensionFunctionsAlwaysPushdown)) {
61
64
  return {
62
65
  recurse: true,
63
66
  result: op,
@@ -65,7 +68,7 @@ class ActorOptimizeQueryOperationFilterPushdown extends bus_optimize_query_opera
65
68
  }
66
69
  // For all filter expressions in the operation,
67
70
  // we attempt to push them down as deep as possible into the algebra.
68
- const variables = self.getExpressionVariables(op.expression);
71
+ const variables = (0, utils_query_operation_1.getExpressionVariables)(op.expression);
69
72
  const [isModified, result] = self
70
73
  .filterPushdown(op.expression, variables, op.input, factory, action.context);
71
74
  if (isModified) {
@@ -107,12 +110,17 @@ class ActorOptimizeQueryOperationFilterPushdown extends bus_optimize_query_opera
107
110
  * Check if the given filter operation must be attempted to push down, based on the following criteria:
108
111
  * - Always push down if aggressive mode is enabled
109
112
  * - Push down if the filter is extremely selective
113
+ * - Don't push down extension functions comunica support, but a source does not
110
114
  * - Push down if federated and at least one accepts the filter
111
115
  * @param operation The filter operation
112
116
  * @param sources The query sources in the operation
113
117
  * @param sourceShapes A mapping of sources to selector shapes.
118
+ * @param extensionFunctions The extension functions comunica supports.
119
+ * @param extensionFunctionsAlwaysPushdown If extension functions must always be pushed down to sources that support
120
+ * expressions, even if those sources to not explicitly declare support for
121
+ * these extension functions.
114
122
  */
115
- shouldAttemptPushDown(operation, sources, sourceShapes) {
123
+ shouldAttemptPushDown(operation, sources, sourceShapes, extensionFunctions, extensionFunctionsAlwaysPushdown) {
116
124
  // Always push down if aggressive mode is enabled
117
125
  if (this.aggressivePushdown) {
118
126
  return true;
@@ -127,8 +135,17 @@ class ActorOptimizeQueryOperationFilterPushdown extends bus_optimize_query_opera
127
135
  expression.args[1].expressionType === 'term' && expression.args[1].term.termType !== 'Variable'))) {
128
136
  return true;
129
137
  }
138
+ // Don't push down extension functions comunica support, but no source does
139
+ if (extensionFunctions && expression.expressionType === sparqlalgebrajs_1.Algebra.expressionTypes.NAMED &&
140
+ expression.name.value in extensionFunctions &&
141
+ // Checks if there's not a single source that supports the extension function
142
+ !sources.some(source => (0, utils_query_operation_1.doesShapeAcceptOperation)(sourceShapes.get(source), expression))) {
143
+ return false;
144
+ }
130
145
  // Push down if federated and at least one accepts the filter
131
- if (sources.some(source => (0, utils_query_operation_1.doesShapeAcceptOperation)(sourceShapes.get(source), operation))) {
146
+ if (sources.some(source => (0, utils_query_operation_1.doesShapeAcceptOperation)(sourceShapes.get(source), operation, {
147
+ wildcardAcceptAllExtensionFunctions: extensionFunctionsAlwaysPushdown,
148
+ }))) {
132
149
  return true;
133
150
  }
134
151
  // Don't push down in all other cases
@@ -155,29 +172,6 @@ class ActorOptimizeQueryOperationFilterPushdown extends bus_optimize_query_opera
155
172
  });
156
173
  return [...sources];
157
174
  }
158
- /**
159
- * Get all variables inside the given expression.
160
- * @param expression An expression.
161
- * @return An array of variables, or undefined if the expression is unsupported for pushdown.
162
- */
163
- getExpressionVariables(expression) {
164
- switch (expression.expressionType) {
165
- case sparqlalgebrajs_1.Algebra.expressionTypes.AGGREGATE:
166
- case sparqlalgebrajs_1.Algebra.expressionTypes.WILDCARD:
167
- throw new Error(`Getting expression variables is not supported for ${expression.expressionType}`);
168
- case sparqlalgebrajs_1.Algebra.expressionTypes.EXISTENCE:
169
- return sparqlalgebrajs_1.Util.inScopeVariables(expression.input);
170
- case sparqlalgebrajs_1.Algebra.expressionTypes.NAMED:
171
- return [];
172
- case sparqlalgebrajs_1.Algebra.expressionTypes.OPERATOR:
173
- return (0, rdf_terms_1.uniqTerms)(expression.args.flatMap(arg => this.getExpressionVariables(arg)));
174
- case sparqlalgebrajs_1.Algebra.expressionTypes.TERM:
175
- if (expression.term.termType === 'Variable') {
176
- return [expression.term];
177
- }
178
- return [];
179
- }
180
- }
181
175
  getOverlappingOperations(operation, expressionVariables) {
182
176
  const fullyOverlapping = [];
183
177
  const partiallyOverlapping = [];
@@ -219,8 +213,7 @@ class ActorOptimizeQueryOperationFilterPushdown extends bus_optimize_query_opera
219
213
  return [true, factory.createUnion([])];
220
214
  }
221
215
  // Don't push down (NOT) EXISTS
222
- if (expression.type === sparqlalgebrajs_1.Algebra.types.EXPRESSION &&
223
- expression.expressionType === sparqlalgebrajs_1.Algebra.expressionTypes.EXISTENCE) {
216
+ if (expression.expressionType === sparqlalgebrajs_1.Algebra.expressionTypes.EXISTENCE) {
224
217
  return [false, factory.createFilter(operation, expression)];
225
218
  }
226
219
  switch (operation.type) {
@@ -1 +1 @@
1
- {"version":3,"file":"ActorOptimizeQueryOperationFilterPushdown.js","sourceRoot":"","sources":["ActorOptimizeQueryOperationFilterPushdown.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n IActionOptimizeQueryOperation,\n IActorOptimizeQueryOperationArgs,\n IActorOptimizeQueryOperationOutput,\n} from '@comunica/bus-optimize-query-operation';\nimport { ActorOptimizeQueryOperation } from '@comunica/bus-optimize-query-operation';\nimport { KeysInitQuery } from '@comunica/context-entries';\nimport type { IActorTest, TestResult } from '@comunica/core';\nimport { passTestVoid } from '@comunica/core';\nimport type { ComunicaDataFactory, FragmentSelectorShape, IActionContext, IQuerySourceWrapper } from '@comunica/types';\nimport { doesShapeAcceptOperation, getOperationSource } from '@comunica/utils-query-operation';\nimport type * as RDF from '@rdfjs/types';\nimport { mapTermsNested, uniqTerms } from 'rdf-terms';\nimport { Factory, Algebra, Util } from 'sparqlalgebrajs';\n\n/**\n * A comunica Filter Pushdown Optimize Query Operation Actor.\n */\nexport class ActorOptimizeQueryOperationFilterPushdown extends ActorOptimizeQueryOperation {\n private readonly aggressivePushdown: boolean;\n private readonly maxIterations: number;\n private readonly splitConjunctive: boolean;\n private readonly mergeConjunctive: boolean;\n private readonly pushIntoLeftJoins: boolean;\n private readonly pushEqualityIntoPatterns: boolean;\n\n public constructor(args: IActorOptimizeQueryOperationFilterPushdownArgs) {\n super(args);\n }\n\n public async test(_action: IActionOptimizeQueryOperation): Promise<TestResult<IActorTest>> {\n return passTestVoid();\n }\n\n public async run(action: IActionOptimizeQueryOperation): Promise<IActorOptimizeQueryOperationOutput> {\n const dataFactory: ComunicaDataFactory = action.context.getSafe(KeysInitQuery.dataFactory);\n const algebraFactory = new Factory(dataFactory);\n let operation: Algebra.Operation = action.operation;\n\n // eslint-disable-next-line ts/no-this-alias\n const self = this;\n\n // Split conjunctive filters into nested filters\n if (this.splitConjunctive) {\n operation = Util.mapOperation(operation, {\n filter(op: Algebra.Filter, factory: Factory) {\n // Split conjunctive filters into separate filters\n if (op.expression.expressionType === Algebra.expressionTypes.OPERATOR && op.expression.operator === '&&') {\n self.logDebug(action.context, `Split conjunctive filter into ${op.expression.args.length} nested filters`);\n return {\n recurse: true,\n result: op.expression.args\n .reduce((operation, expression) => factory.createFilter(operation, expression), op.input),\n };\n }\n return {\n recurse: true,\n result: op,\n };\n },\n }, algebraFactory);\n }\n\n // Collect selector shapes of all operations\n const sources = this.getSources(operation);\n // eslint-disable-next-line ts/no-unnecessary-type-assertion\n const sourceShapes = new Map(<[IQuerySourceWrapper, FragmentSelectorShape][]> await Promise.all(sources\n .map(async source => [ source, await source.source.getSelectorShape(action.context) ])));\n\n // Push down all filters\n // We loop until no more filters can be pushed down.\n let repeat = true;\n let iterations = 0;\n while (repeat && iterations < this.maxIterations) {\n repeat = false;\n operation = Util.mapOperation(operation, {\n filter(op: Algebra.Filter, factory: Factory) {\n // Check if the filter must be pushed down\n if (!self.shouldAttemptPushDown(op, sources, sourceShapes)) {\n return {\n recurse: true,\n result: op,\n };\n }\n\n // For all filter expressions in the operation,\n // we attempt to push them down as deep as possible into the algebra.\n const variables = self.getExpressionVariables(op.expression);\n const [ isModified, result ] = self\n .filterPushdown(op.expression, variables, op.input, factory, action.context);\n if (isModified) {\n repeat = true;\n }\n return {\n recurse: true,\n result,\n };\n },\n });\n iterations++;\n }\n\n if (iterations > 1) {\n self.logDebug(action.context, `Pushed down filters in ${iterations} iterations`);\n }\n\n // Merge nested filters into conjunctive filters\n if (this.mergeConjunctive) {\n operation = Util.mapOperation(operation, {\n filter(op: Algebra.Filter, factory: Factory) {\n if (op.input.type === Algebra.types.FILTER) {\n const { nestedExpressions, input } = self.getNestedFilterExpressions(op);\n self.logDebug(action.context, `Merge ${nestedExpressions.length} nested filters into conjunctive filter`);\n return {\n recurse: true,\n result: factory.createFilter(\n input,\n nestedExpressions.slice(1).reduce((previous, current) =>\n factory.createOperatorExpression('&&', [ previous, current ]), nestedExpressions[0]),\n ),\n };\n }\n return {\n recurse: true,\n result: op,\n };\n },\n });\n }\n\n return { operation, context: action.context };\n }\n\n /**\n * Check if the given filter operation must be attempted to push down, based on the following criteria:\n * - Always push down if aggressive mode is enabled\n * - Push down if the filter is extremely selective\n * - Push down if federated and at least one accepts the filter\n * @param operation The filter operation\n * @param sources The query sources in the operation\n * @param sourceShapes A mapping of sources to selector shapes.\n */\n public shouldAttemptPushDown(\n operation: Algebra.Filter,\n sources: IQuerySourceWrapper[],\n sourceShapes: Map<IQuerySourceWrapper, FragmentSelectorShape>,\n ): boolean {\n // Always push down if aggressive mode is enabled\n if (this.aggressivePushdown) {\n return true;\n }\n\n // Push down if the filter is extremely selective\n const expression = operation.expression;\n if (expression.expressionType === Algebra.expressionTypes.OPERATOR &&\n expression.operator === '=' &&\n ((expression.args[0].expressionType === 'term' && expression.args[0].term.termType !== 'Variable' &&\n expression.args[1].expressionType === 'term' && expression.args[1].term.termType === 'Variable') ||\n (expression.args[0].expressionType === 'term' && expression.args[0].term.termType === 'Variable' &&\n expression.args[1].expressionType === 'term' && expression.args[1].term.termType !== 'Variable'))) {\n return true;\n }\n\n // Push down if federated and at least one accepts the filter\n if (sources.some(source => doesShapeAcceptOperation(sourceShapes.get(source)!, operation))) {\n return true;\n }\n\n // Don't push down in all other cases\n return false;\n }\n\n /**\n * Collected all sources that are defined within the given operation of children recursively.\n * @param operation An operation.\n */\n public getSources(operation: Algebra.Operation): IQuerySourceWrapper[] {\n const sources = new Set<IQuerySourceWrapper>();\n const sourceAdder = (subOperation: Algebra.Operation): boolean => {\n const src = getOperationSource(subOperation);\n if (src) {\n sources.add(src);\n }\n return false;\n };\n Util.recurseOperation(operation, {\n [Algebra.types.PATTERN]: sourceAdder,\n [Algebra.types.LINK]: sourceAdder,\n [Algebra.types.NPS]: sourceAdder,\n [Algebra.types.SERVICE]: sourceAdder,\n });\n return [ ...sources ];\n }\n\n /**\n * Get all variables inside the given expression.\n * @param expression An expression.\n * @return An array of variables, or undefined if the expression is unsupported for pushdown.\n */\n public getExpressionVariables(expression: Algebra.Expression): RDF.Variable[] {\n switch (expression.expressionType) {\n case Algebra.expressionTypes.AGGREGATE:\n case Algebra.expressionTypes.WILDCARD:\n throw new Error(`Getting expression variables is not supported for ${expression.expressionType}`);\n case Algebra.expressionTypes.EXISTENCE:\n return Util.inScopeVariables(expression.input);\n case Algebra.expressionTypes.NAMED:\n return [];\n case Algebra.expressionTypes.OPERATOR:\n return uniqTerms(expression.args.flatMap(arg => this.getExpressionVariables(arg)));\n case Algebra.expressionTypes.TERM:\n if (expression.term.termType === 'Variable') {\n return [ expression.term ];\n }\n return [];\n }\n }\n\n protected getOverlappingOperations(\n operation: Algebra.Operation,\n expressionVariables: RDF.Variable[],\n ): {\n fullyOverlapping: Algebra.Operation[];\n partiallyOverlapping: Algebra.Operation[];\n notOverlapping: Algebra.Operation[];\n } {\n const fullyOverlapping: Algebra.Operation[] = [];\n const partiallyOverlapping: Algebra.Operation[] = [];\n const notOverlapping: Algebra.Operation[] = [];\n for (const input of operation.input) {\n const inputVariables = Util.inScopeVariables(input);\n if (this.variablesSubSetOf(expressionVariables, inputVariables)) {\n fullyOverlapping.push(input);\n } else if (this.variablesIntersect(expressionVariables, inputVariables)) {\n partiallyOverlapping.push(input);\n } else {\n notOverlapping.push(input);\n }\n }\n\n return {\n fullyOverlapping,\n partiallyOverlapping,\n notOverlapping,\n };\n }\n\n /**\n * Recursively push down the given expression into the given operation if possible.\n * Different operators have different semantics for choosing whether or not to push down,\n * and how this pushdown is done.\n * For every passed operator, it is checked whether or not the filter will have any effect on the operation.\n * If not, the filter is voided.\n * @param expression An expression to push down.\n * @param expressionVariables The variables inside the given expression.\n * @param operation The operation to push down into.\n * @param factory An algebra factory.\n * @param context The action context.\n * @return A tuple indicating if the operation was modified and the modified operation.\n */\n public filterPushdown(\n expression: Algebra.Expression,\n expressionVariables: RDF.Variable[],\n operation: Algebra.Operation,\n factory: Factory,\n context: IActionContext,\n ): [ boolean, Algebra.Operation ] {\n // Void false expressions\n if (this.isExpressionFalse(expression)) {\n return [ true, factory.createUnion([]) ];\n }\n\n // Don't push down (NOT) EXISTS\n if (expression.type === Algebra.types.EXPRESSION &&\n expression.expressionType === Algebra.expressionTypes.EXISTENCE) {\n return [ false, factory.createFilter(operation, expression) ];\n }\n\n switch (operation.type) {\n case Algebra.types.EXTEND:\n // Pass if the variable is not part of the expression\n if (!this.variablesIntersect([ operation.variable ], expressionVariables)) {\n return [ true, factory.createExtend(\n this.filterPushdown(expression, expressionVariables, operation.input, factory, context)[1],\n operation.variable,\n operation.expression,\n ) ];\n }\n return [ false, factory.createFilter(operation, expression) ];\n case Algebra.types.FILTER: {\n // Always pass\n const [ isModified, result ] = this\n .filterPushdown(expression, expressionVariables, operation.input, factory, context);\n return [ isModified, factory.createFilter(result, operation.expression) ];\n }\n case Algebra.types.JOIN: {\n // Don't push down for empty join\n if (operation.input.length === 0) {\n return [ false, factory.createFilter(operation, expression) ];\n }\n\n // Determine overlapping operations\n const {\n fullyOverlapping,\n partiallyOverlapping,\n notOverlapping,\n } = this.getOverlappingOperations(operation, expressionVariables);\n\n const joins: Algebra.Operation[] = [];\n let isModified = false;\n if (fullyOverlapping.length > 0) {\n isModified = true;\n joins.push(factory.createJoin(fullyOverlapping\n .map(input => this.filterPushdown(expression, expressionVariables, input, factory, context)[1])));\n }\n if (partiallyOverlapping.length > 0) {\n joins.push(factory.createFilter(factory.createJoin(partiallyOverlapping, false), expression));\n }\n if (notOverlapping.length > 0) {\n joins.push(...notOverlapping);\n }\n\n if (joins.length > 1) {\n isModified = true;\n }\n\n if (isModified) {\n this.logDebug(context, `Push down filter across join entries with ${fullyOverlapping.length} fully overlapping, ${partiallyOverlapping.length} partially overlapping, and ${notOverlapping.length} not overlapping`);\n }\n\n return [ isModified, joins.length === 1 ? joins[0] : factory.createJoin(joins) ];\n }\n case Algebra.types.NOP:\n return [ true, operation ];\n case Algebra.types.PROJECT:\n // Push down if variables overlap\n if (this.variablesIntersect(operation.variables, expressionVariables)) {\n return [ true, factory.createProject(\n this.filterPushdown(expression, expressionVariables, operation.input, factory, context)[1],\n operation.variables,\n ) ];\n }\n // Void expression otherwise\n return [ true, operation ];\n case Algebra.types.UNION: {\n // Determine overlapping operations\n const {\n fullyOverlapping,\n partiallyOverlapping,\n notOverlapping,\n } = this.getOverlappingOperations(operation, expressionVariables);\n\n const unions: Algebra.Operation[] = [];\n let isModified = false;\n if (fullyOverlapping.length > 0) {\n isModified = true;\n unions.push(factory.createUnion(fullyOverlapping\n .map(input => this.filterPushdown(expression, expressionVariables, input, factory, context)[1])));\n }\n if (partiallyOverlapping.length > 0) {\n unions.push(factory.createFilter(factory.createUnion(partiallyOverlapping, false), expression));\n }\n if (notOverlapping.length > 0) {\n unions.push(...notOverlapping);\n }\n\n if (unions.length > 1) {\n isModified = true;\n }\n\n if (isModified) {\n this.logDebug(context, `Push down filter across union entries with ${fullyOverlapping.length} fully overlapping, ${partiallyOverlapping.length} partially overlapping, and ${notOverlapping.length} not overlapping`);\n }\n\n return [ isModified, unions.length === 1 ? unions[0] : factory.createUnion(unions) ];\n }\n case Algebra.types.VALUES:\n // Only keep filter if it overlaps with the variables\n if (this.variablesIntersect(operation.variables, expressionVariables)) {\n return [ false, factory.createFilter(operation, expression) ];\n }\n return [ true, operation ];\n case Algebra.types.LEFT_JOIN: {\n if (this.pushIntoLeftJoins) {\n const rightVariables = Util.inScopeVariables(operation.input[1]);\n if (!this.variablesIntersect(expressionVariables, rightVariables)) {\n // If filter *only* applies to left entry of optional, push it down into that.\n this.logDebug(context, `Push down filter into left join`);\n return [ true, factory.createLeftJoin(\n this.filterPushdown(expression, expressionVariables, operation.input[0], factory, context)[1],\n operation.input[1],\n operation.expression,\n ) ];\n }\n }\n\n // Don't push down in all other cases\n return [ false, factory.createFilter(operation, expression) ];\n }\n case Algebra.types.PATTERN: {\n if (this.pushEqualityIntoPatterns) {\n // Try to push simple FILTER(?s = <iri>) expressions into the pattern\n const pushableResult = this.getEqualityExpressionPushableIntoPattern(expression);\n if (pushableResult) {\n let isModified = false;\n const originalMetadata = operation.metadata;\n operation = mapTermsNested(operation, (value) => {\n if (value.equals(pushableResult.variable)) {\n isModified = true;\n return pushableResult.term;\n }\n return value;\n });\n operation.type = Algebra.types.PATTERN;\n operation.metadata = originalMetadata;\n if (isModified) {\n this.logDebug(context, `Push down filter into pattern for ?${pushableResult.variable.value}`);\n return [ true, factory.createJoin([\n operation,\n factory.createValues(\n [ pushableResult.variable ],\n [{ [`?${pushableResult.variable.value}`]: <RDF.NamedNode | RDF.Literal> pushableResult.term }],\n ),\n ]) ];\n }\n }\n }\n\n // Don't push down in all other cases\n return [ false, factory.createFilter(operation, expression) ];\n }\n case Algebra.types.PATH: {\n if (this.pushEqualityIntoPatterns) {\n // Try to push simple FILTER(?s = <iri>) expressions into the path\n const pushableResult = this.getEqualityExpressionPushableIntoPattern(expression);\n if (pushableResult &&\n (operation.subject.equals(pushableResult.variable) || operation.object.equals(pushableResult.variable))) {\n this.logDebug(context, `Push down filter into path for ?${pushableResult.variable.value}`);\n const originalMetadata = operation.metadata;\n operation = factory.createPath(\n operation.subject.equals(pushableResult.variable) ? pushableResult.term : operation.subject,\n operation.predicate,\n operation.object.equals(pushableResult.variable) ? pushableResult.term : operation.object,\n );\n operation.metadata = originalMetadata;\n return [ true, factory.createJoin([\n operation,\n factory.createValues(\n [ pushableResult.variable ],\n [{ [`?${pushableResult.variable.value}`]: <RDF.NamedNode | RDF.Literal> pushableResult.term }],\n ),\n ]) ];\n }\n }\n\n // Don't push down in all other cases\n return [ false, factory.createFilter(operation, expression) ];\n }\n case Algebra.types.MINUS:\n case Algebra.types.ALT:\n case Algebra.types.ASK:\n case Algebra.types.BGP:\n case Algebra.types.CONSTRUCT:\n case Algebra.types.DESCRIBE:\n case Algebra.types.DISTINCT:\n case Algebra.types.EXPRESSION:\n case Algebra.types.FROM:\n case Algebra.types.GRAPH:\n case Algebra.types.GROUP:\n case Algebra.types.INV:\n case Algebra.types.LINK:\n case Algebra.types.NPS:\n case Algebra.types.ONE_OR_MORE_PATH:\n case Algebra.types.ORDER_BY:\n case Algebra.types.REDUCED:\n case Algebra.types.SEQ:\n case Algebra.types.SERVICE:\n case Algebra.types.SLICE:\n case Algebra.types.ZERO_OR_MORE_PATH:\n case Algebra.types.ZERO_OR_ONE_PATH:\n case Algebra.types.COMPOSITE_UPDATE:\n case Algebra.types.DELETE_INSERT:\n case Algebra.types.LOAD:\n case Algebra.types.CLEAR:\n case Algebra.types.CREATE:\n case Algebra.types.DROP:\n case Algebra.types.ADD:\n case Algebra.types.MOVE:\n case Algebra.types.COPY:\n // Operations that do not support pushing down\n // Left-join and minus might be possible to support in the future.\n return [ false, factory.createFilter(operation, expression) ];\n }\n }\n\n /**\n * Check if the given expression is a simple equals operation with one variable and one non-literal\n * (or literal with canonical lexical form) term that can be pushed into a pattern.\n * @param expression The current expression.\n * @return The variable and term to fill into the pattern, or undefined.\n */\n public getEqualityExpressionPushableIntoPattern(\n expression: Algebra.Expression,\n ): { variable: RDF.Variable; term: RDF.Term } | undefined {\n if (expression.expressionType === Algebra.expressionTypes.OPERATOR && expression.operator === '=') {\n if (expression.args[0].expressionType === 'term' && expression.args[0].term.termType !== 'Variable' &&\n (expression.args[0].term.termType !== 'Literal' ||\n this.isLiteralWithCanonicalLexicalForm(expression.args[0].term)) &&\n expression.args[1].expressionType === 'term' && expression.args[1].term.termType === 'Variable') {\n return {\n variable: expression.args[1].term,\n term: expression.args[0].term,\n };\n }\n if (expression.args[0].expressionType === 'term' && expression.args[0].term.termType === 'Variable' &&\n expression.args[1].expressionType === 'term' && expression.args[1].term.termType !== 'Variable' &&\n (expression.args[1].term.termType !== 'Literal' ||\n this.isLiteralWithCanonicalLexicalForm(expression.args[1].term))) {\n return {\n variable: expression.args[0].term,\n term: expression.args[1].term,\n };\n }\n }\n }\n\n /**\n * Check if the given term is a literal with datatype that where all values\n * can only have one possible lexical representation.\n * In other words, no variants of values exist that should be considered equal.\n * For example: \"01\"^xsd:number and \"1\"^xsd:number will return false.\n * @param term An RDF term.\n * @protected\n */\n protected isLiteralWithCanonicalLexicalForm(term: RDF.Term): boolean {\n if (term.termType === 'Literal') {\n switch (term.datatype.value) {\n case 'http://www.w3.org/2001/XMLSchema#string':\n case 'http://www.w3.org/1999/02/22-rdf-syntax-ns#langString':\n case 'http://www.w3.org/2001/XMLSchema#normalizedString':\n case 'http://www.w3.org/2001/XMLSchema#anyURI':\n case 'http://www.w3.org/2001/XMLSchema#base64Binary':\n case 'http://www.w3.org/2001/XMLSchema#language':\n case 'http://www.w3.org/2001/XMLSchema#Name':\n case 'http://www.w3.org/2001/XMLSchema#NCName':\n case 'http://www.w3.org/2001/XMLSchema#NMTOKEN':\n case 'http://www.w3.org/2001/XMLSchema#token':\n case 'http://www.w3.org/2001/XMLSchema#hexBinary':\n return true;\n }\n }\n return false;\n }\n\n /**\n * Check if there is an overlap between the two given lists of variables.\n * @param varsA A list of variables.\n * @param varsB A list of variables.\n */\n public variablesIntersect(varsA: RDF.Variable[], varsB: RDF.Variable[]): boolean {\n return varsA.some(varA => varsB.some(varB => varA.equals(varB)));\n }\n\n /**\n * Check if all variables from the first list are included in the second list.\n * The second list may contain other variables as well.\n * @param varsNeedles A list of variables to search for.\n * @param varsHaystack A list of variables to search in.\n */\n public variablesSubSetOf(varsNeedles: RDF.Variable[], varsHaystack: RDF.Variable[]): boolean {\n return varsNeedles.length <= varsHaystack.length &&\n varsNeedles.every(varA => varsHaystack.some(varB => varA.equals(varB)));\n }\n\n /**\n * Check if an expression is simply 'false'.\n * @param expression An expression.\n */\n public isExpressionFalse(expression: Algebra.Expression): boolean {\n return (expression.term && expression.term.termType === 'Literal' && expression.term.value === 'false');\n }\n\n /**\n * Get all directly nested filter expressions.\n * As soon as a non-filter is found, it is returned as the input field.\n * @param op A filter expression.\n */\n public getNestedFilterExpressions(\n op: Algebra.Filter,\n ): { nestedExpressions: Algebra.Expression[]; input: Algebra.Operation } {\n if (op.input.type === Algebra.types.FILTER) {\n const childData = this.getNestedFilterExpressions(op.input);\n return { nestedExpressions: [ op.expression, ...childData.nestedExpressions ], input: childData.input };\n }\n return { nestedExpressions: [ op.expression ], input: op.input };\n }\n}\n\nexport interface IActorOptimizeQueryOperationFilterPushdownArgs extends IActorOptimizeQueryOperationArgs {\n /**\n * If filters should be pushed down as deep as possible.\n * If false, filters will only be pushed down if the source(s) accept them,\n * or if the filter is very selective.\n * @range {boolean}\n * @default {false}\n */\n aggressivePushdown: boolean;\n /**\n * The maximum number of full iterations across the query can be done for attempting to push down filters.\n * @default {10}\n */\n maxIterations: number;\n /**\n * If conjunctive filters should be split into nested filters before applying filter pushdown.\n * This can enable pushing down deeper.\n * @range {boolean}\n * @default {true}\n */\n splitConjunctive: boolean;\n /**\n * If nested filters should be merged into conjunctive filters after applying filter pushdown.\n * @range {boolean}\n * @default {true}\n */\n mergeConjunctive: boolean;\n /**\n * If filters should be pushed into left-joins.\n * @range {boolean}\n * @default {true}\n */\n pushIntoLeftJoins: boolean;\n /**\n * If simple equality filters should be pushed into patterns and paths.\n * This only applies to equality filters with terms that are not literals that have no canonical lexical form.\n * @range {boolean}\n * @default {true}\n */\n pushEqualityIntoPatterns: boolean;\n}\n"]}
1
+ {"version":3,"file":"ActorOptimizeQueryOperationFilterPushdown.js","sourceRoot":"","sources":["ActorOptimizeQueryOperationFilterPushdown.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n IActionOptimizeQueryOperation,\n IActorOptimizeQueryOperationArgs,\n IActorOptimizeQueryOperationOutput,\n} from '@comunica/bus-optimize-query-operation';\nimport { ActorOptimizeQueryOperation } from '@comunica/bus-optimize-query-operation';\nimport { KeysInitQuery } from '@comunica/context-entries';\nimport type { IActorTest, TestResult } from '@comunica/core';\nimport { passTestVoid } from '@comunica/core';\nimport type {\n ComunicaDataFactory,\n FragmentSelectorShape,\n IActionContext,\n IQuerySourceWrapper,\n} from '@comunica/types';\nimport {\n doesShapeAcceptOperation,\n getExpressionVariables,\n getOperationSource,\n} from '@comunica/utils-query-operation';\nimport type * as RDF from '@rdfjs/types';\nimport { mapTermsNested } from 'rdf-terms';\nimport { Factory, Algebra, Util } from 'sparqlalgebrajs';\n\n/**\n * A comunica Filter Pushdown Optimize Query Operation Actor.\n */\nexport class ActorOptimizeQueryOperationFilterPushdown extends ActorOptimizeQueryOperation {\n private readonly aggressivePushdown: boolean;\n private readonly maxIterations: number;\n private readonly splitConjunctive: boolean;\n private readonly mergeConjunctive: boolean;\n private readonly pushIntoLeftJoins: boolean;\n private readonly pushEqualityIntoPatterns: boolean;\n\n public constructor(args: IActorOptimizeQueryOperationFilterPushdownArgs) {\n super(args);\n }\n\n public async test(_action: IActionOptimizeQueryOperation): Promise<TestResult<IActorTest>> {\n return passTestVoid();\n }\n\n public async run(action: IActionOptimizeQueryOperation): Promise<IActorOptimizeQueryOperationOutput> {\n const dataFactory: ComunicaDataFactory = action.context.getSafe(KeysInitQuery.dataFactory);\n const algebraFactory = new Factory(dataFactory);\n let operation: Algebra.Operation = action.operation;\n\n // eslint-disable-next-line ts/no-this-alias\n const self = this;\n\n // Split conjunctive filters into nested filters\n if (this.splitConjunctive) {\n operation = Util.mapOperation(operation, {\n filter(op: Algebra.Filter, factory: Factory) {\n // Split conjunctive filters into separate filters\n if (op.expression.expressionType === Algebra.expressionTypes.OPERATOR && op.expression.operator === '&&') {\n self.logDebug(action.context, `Split conjunctive filter into ${op.expression.args.length} nested filters`);\n return {\n recurse: true,\n result: op.expression.args\n .reduce((operation, expression) => factory.createFilter(operation, expression), op.input),\n };\n }\n return {\n recurse: true,\n result: op,\n };\n },\n }, algebraFactory);\n }\n\n // Collect selector shapes of all operations\n const sources = this.getSources(operation);\n // eslint-disable-next-line ts/no-unnecessary-type-assertion\n const sourceShapes = new Map(<[IQuerySourceWrapper, FragmentSelectorShape][]> await Promise.all(sources\n .map(async source => [ source, await source.source.getSelectorShape(action.context) ])));\n\n // Push down all filters\n // We loop until no more filters can be pushed down.\n let repeat = true;\n let iterations = 0;\n while (repeat && iterations < this.maxIterations) {\n repeat = false;\n operation = Util.mapOperation(operation, {\n filter(op: Algebra.Filter, factory: Factory) {\n // Check if the filter must be pushed down\n const extensionFunctions = action.context.get(KeysInitQuery.extensionFunctions);\n const extensionFunctionsAlwaysPushdown = action.context.get(KeysInitQuery.extensionFunctionsAlwaysPushdown);\n if (!self\n .shouldAttemptPushDown(op, sources, sourceShapes, extensionFunctions, extensionFunctionsAlwaysPushdown)) {\n return {\n recurse: true,\n result: op,\n };\n }\n\n // For all filter expressions in the operation,\n // we attempt to push them down as deep as possible into the algebra.\n const variables = getExpressionVariables(op.expression);\n const [ isModified, result ] = self\n .filterPushdown(op.expression, variables, op.input, factory, action.context);\n if (isModified) {\n repeat = true;\n }\n return {\n recurse: true,\n result,\n };\n },\n });\n iterations++;\n }\n\n if (iterations > 1) {\n self.logDebug(action.context, `Pushed down filters in ${iterations} iterations`);\n }\n\n // Merge nested filters into conjunctive filters\n if (this.mergeConjunctive) {\n operation = Util.mapOperation(operation, {\n filter(op: Algebra.Filter, factory: Factory) {\n if (op.input.type === Algebra.types.FILTER) {\n const { nestedExpressions, input } = self.getNestedFilterExpressions(op);\n self.logDebug(action.context, `Merge ${nestedExpressions.length} nested filters into conjunctive filter`);\n return {\n recurse: true,\n result: factory.createFilter(\n input,\n nestedExpressions.slice(1).reduce((previous, current) =>\n factory.createOperatorExpression('&&', [ previous, current ]), nestedExpressions[0]),\n ),\n };\n }\n return {\n recurse: true,\n result: op,\n };\n },\n });\n }\n\n return { operation, context: action.context };\n }\n\n /**\n * Check if the given filter operation must be attempted to push down, based on the following criteria:\n * - Always push down if aggressive mode is enabled\n * - Push down if the filter is extremely selective\n * - Don't push down extension functions comunica support, but a source does not\n * - Push down if federated and at least one accepts the filter\n * @param operation The filter operation\n * @param sources The query sources in the operation\n * @param sourceShapes A mapping of sources to selector shapes.\n * @param extensionFunctions The extension functions comunica supports.\n * @param extensionFunctionsAlwaysPushdown If extension functions must always be pushed down to sources that support\n * expressions, even if those sources to not explicitly declare support for\n * these extension functions.\n */\n public shouldAttemptPushDown(\n operation: Algebra.Filter,\n sources: IQuerySourceWrapper[],\n sourceShapes: Map<IQuerySourceWrapper, FragmentSelectorShape>,\n extensionFunctions?: Record<string, any>,\n extensionFunctionsAlwaysPushdown?: boolean,\n ): boolean {\n // Always push down if aggressive mode is enabled\n if (this.aggressivePushdown) {\n return true;\n }\n\n // Push down if the filter is extremely selective\n const expression = operation.expression;\n if (expression.expressionType === Algebra.expressionTypes.OPERATOR &&\n expression.operator === '=' &&\n ((expression.args[0].expressionType === 'term' && expression.args[0].term.termType !== 'Variable' &&\n expression.args[1].expressionType === 'term' && expression.args[1].term.termType === 'Variable') ||\n (expression.args[0].expressionType === 'term' && expression.args[0].term.termType === 'Variable' &&\n expression.args[1].expressionType === 'term' && expression.args[1].term.termType !== 'Variable'))) {\n return true;\n }\n\n // Don't push down extension functions comunica support, but no source does\n if (extensionFunctions && expression.expressionType === Algebra.expressionTypes.NAMED &&\n expression.name.value in extensionFunctions &&\n // Checks if there's not a single source that supports the extension function\n !sources.some(source =>\n doesShapeAcceptOperation(sourceShapes.get(source)!, expression))\n ) {\n return false;\n }\n\n // Push down if federated and at least one accepts the filter\n if (sources.some(source => doesShapeAcceptOperation(sourceShapes.get(source)!, operation, {\n wildcardAcceptAllExtensionFunctions: extensionFunctionsAlwaysPushdown,\n }))) {\n return true;\n }\n\n // Don't push down in all other cases\n return false;\n }\n\n /**\n * Collected all sources that are defined within the given operation of children recursively.\n * @param operation An operation.\n */\n public getSources(operation: Algebra.Operation): IQuerySourceWrapper[] {\n const sources = new Set<IQuerySourceWrapper>();\n const sourceAdder = (subOperation: Algebra.Operation): boolean => {\n const src = getOperationSource(subOperation);\n if (src) {\n sources.add(src);\n }\n return false;\n };\n Util.recurseOperation(operation, {\n [Algebra.types.PATTERN]: sourceAdder,\n [Algebra.types.LINK]: sourceAdder,\n [Algebra.types.NPS]: sourceAdder,\n [Algebra.types.SERVICE]: sourceAdder,\n });\n return [ ...sources ];\n }\n\n protected getOverlappingOperations(\n operation: Algebra.Operation,\n expressionVariables: RDF.Variable[],\n ): {\n fullyOverlapping: Algebra.Operation[];\n partiallyOverlapping: Algebra.Operation[];\n notOverlapping: Algebra.Operation[];\n } {\n const fullyOverlapping: Algebra.Operation[] = [];\n const partiallyOverlapping: Algebra.Operation[] = [];\n const notOverlapping: Algebra.Operation[] = [];\n for (const input of operation.input) {\n const inputVariables = Util.inScopeVariables(input);\n if (this.variablesSubSetOf(expressionVariables, inputVariables)) {\n fullyOverlapping.push(input);\n } else if (this.variablesIntersect(expressionVariables, inputVariables)) {\n partiallyOverlapping.push(input);\n } else {\n notOverlapping.push(input);\n }\n }\n\n return {\n fullyOverlapping,\n partiallyOverlapping,\n notOverlapping,\n };\n }\n\n /**\n * Recursively push down the given expression into the given operation if possible.\n * Different operators have different semantics for choosing whether or not to push down,\n * and how this pushdown is done.\n * For every passed operator, it is checked whether or not the filter will have any effect on the operation.\n * If not, the filter is voided.\n * @param expression An expression to push down.\n * @param expressionVariables The variables inside the given expression.\n * @param operation The operation to push down into.\n * @param factory An algebra factory.\n * @param context The action context.\n * @return A tuple indicating if the operation was modified and the modified operation.\n */\n public filterPushdown(\n expression: Algebra.Expression,\n expressionVariables: RDF.Variable[],\n operation: Algebra.Operation,\n factory: Factory,\n context: IActionContext,\n ): [ boolean, Algebra.Operation ] {\n // Void false expressions\n if (this.isExpressionFalse(expression)) {\n return [ true, factory.createUnion([]) ];\n }\n\n // Don't push down (NOT) EXISTS\n if (expression.expressionType === Algebra.expressionTypes.EXISTENCE) {\n return [ false, factory.createFilter(operation, expression) ];\n }\n\n switch (operation.type) {\n case Algebra.types.EXTEND:\n // Pass if the variable is not part of the expression\n if (!this.variablesIntersect([ operation.variable ], expressionVariables)) {\n return [ true, factory.createExtend(\n this.filterPushdown(expression, expressionVariables, operation.input, factory, context)[1],\n operation.variable,\n operation.expression,\n ) ];\n }\n return [ false, factory.createFilter(operation, expression) ];\n case Algebra.types.FILTER: {\n // Always pass\n const [ isModified, result ] = this\n .filterPushdown(expression, expressionVariables, operation.input, factory, context);\n return [ isModified, factory.createFilter(result, operation.expression) ];\n }\n case Algebra.types.JOIN: {\n // Don't push down for empty join\n if (operation.input.length === 0) {\n return [ false, factory.createFilter(operation, expression) ];\n }\n\n // Determine overlapping operations\n const {\n fullyOverlapping,\n partiallyOverlapping,\n notOverlapping,\n } = this.getOverlappingOperations(operation, expressionVariables);\n\n const joins: Algebra.Operation[] = [];\n let isModified = false;\n if (fullyOverlapping.length > 0) {\n isModified = true;\n joins.push(factory.createJoin(fullyOverlapping\n .map(input => this.filterPushdown(expression, expressionVariables, input, factory, context)[1])));\n }\n if (partiallyOverlapping.length > 0) {\n joins.push(factory.createFilter(factory.createJoin(partiallyOverlapping, false), expression));\n }\n if (notOverlapping.length > 0) {\n joins.push(...notOverlapping);\n }\n\n if (joins.length > 1) {\n isModified = true;\n }\n\n if (isModified) {\n this.logDebug(context, `Push down filter across join entries with ${fullyOverlapping.length} fully overlapping, ${partiallyOverlapping.length} partially overlapping, and ${notOverlapping.length} not overlapping`);\n }\n\n return [ isModified, joins.length === 1 ? joins[0] : factory.createJoin(joins) ];\n }\n case Algebra.types.NOP:\n return [ true, operation ];\n case Algebra.types.PROJECT:\n // Push down if variables overlap\n if (this.variablesIntersect(operation.variables, expressionVariables)) {\n return [ true, factory.createProject(\n this.filterPushdown(expression, expressionVariables, operation.input, factory, context)[1],\n operation.variables,\n ) ];\n }\n // Void expression otherwise\n return [ true, operation ];\n case Algebra.types.UNION: {\n // Determine overlapping operations\n const {\n fullyOverlapping,\n partiallyOverlapping,\n notOverlapping,\n } = this.getOverlappingOperations(operation, expressionVariables);\n\n const unions: Algebra.Operation[] = [];\n let isModified = false;\n if (fullyOverlapping.length > 0) {\n isModified = true;\n unions.push(factory.createUnion(fullyOverlapping\n .map(input => this.filterPushdown(expression, expressionVariables, input, factory, context)[1])));\n }\n if (partiallyOverlapping.length > 0) {\n unions.push(factory.createFilter(factory.createUnion(partiallyOverlapping, false), expression));\n }\n if (notOverlapping.length > 0) {\n unions.push(...notOverlapping);\n }\n\n if (unions.length > 1) {\n isModified = true;\n }\n\n if (isModified) {\n this.logDebug(context, `Push down filter across union entries with ${fullyOverlapping.length} fully overlapping, ${partiallyOverlapping.length} partially overlapping, and ${notOverlapping.length} not overlapping`);\n }\n\n return [ isModified, unions.length === 1 ? unions[0] : factory.createUnion(unions) ];\n }\n case Algebra.types.VALUES:\n // Only keep filter if it overlaps with the variables\n if (this.variablesIntersect(operation.variables, expressionVariables)) {\n return [ false, factory.createFilter(operation, expression) ];\n }\n return [ true, operation ];\n case Algebra.types.LEFT_JOIN: {\n if (this.pushIntoLeftJoins) {\n const rightVariables = Util.inScopeVariables(operation.input[1]);\n if (!this.variablesIntersect(expressionVariables, rightVariables)) {\n // If filter *only* applies to left entry of optional, push it down into that.\n this.logDebug(context, `Push down filter into left join`);\n return [ true, factory.createLeftJoin(\n this.filterPushdown(expression, expressionVariables, operation.input[0], factory, context)[1],\n operation.input[1],\n operation.expression,\n ) ];\n }\n }\n\n // Don't push down in all other cases\n return [ false, factory.createFilter(operation, expression) ];\n }\n case Algebra.types.PATTERN: {\n if (this.pushEqualityIntoPatterns) {\n // Try to push simple FILTER(?s = <iri>) expressions into the pattern\n const pushableResult = this.getEqualityExpressionPushableIntoPattern(expression);\n if (pushableResult) {\n let isModified = false;\n const originalMetadata = operation.metadata;\n operation = mapTermsNested(operation, (value) => {\n if (value.equals(pushableResult.variable)) {\n isModified = true;\n return pushableResult.term;\n }\n return value;\n });\n operation.type = Algebra.types.PATTERN;\n operation.metadata = originalMetadata;\n if (isModified) {\n this.logDebug(context, `Push down filter into pattern for ?${pushableResult.variable.value}`);\n return [ true, factory.createJoin([\n operation,\n factory.createValues(\n [ pushableResult.variable ],\n [{ [`?${pushableResult.variable.value}`]: <RDF.NamedNode | RDF.Literal> pushableResult.term }],\n ),\n ]) ];\n }\n }\n }\n\n // Don't push down in all other cases\n return [ false, factory.createFilter(operation, expression) ];\n }\n case Algebra.types.PATH: {\n if (this.pushEqualityIntoPatterns) {\n // Try to push simple FILTER(?s = <iri>) expressions into the path\n const pushableResult = this.getEqualityExpressionPushableIntoPattern(expression);\n if (pushableResult &&\n (operation.subject.equals(pushableResult.variable) || operation.object.equals(pushableResult.variable))) {\n this.logDebug(context, `Push down filter into path for ?${pushableResult.variable.value}`);\n const originalMetadata = operation.metadata;\n operation = factory.createPath(\n operation.subject.equals(pushableResult.variable) ? pushableResult.term : operation.subject,\n operation.predicate,\n operation.object.equals(pushableResult.variable) ? pushableResult.term : operation.object,\n );\n operation.metadata = originalMetadata;\n return [ true, factory.createJoin([\n operation,\n factory.createValues(\n [ pushableResult.variable ],\n [{ [`?${pushableResult.variable.value}`]: <RDF.NamedNode | RDF.Literal> pushableResult.term }],\n ),\n ]) ];\n }\n }\n\n // Don't push down in all other cases\n return [ false, factory.createFilter(operation, expression) ];\n }\n case Algebra.types.MINUS:\n case Algebra.types.ALT:\n case Algebra.types.ASK:\n case Algebra.types.BGP:\n case Algebra.types.CONSTRUCT:\n case Algebra.types.DESCRIBE:\n case Algebra.types.DISTINCT:\n case Algebra.types.EXPRESSION:\n case Algebra.types.FROM:\n case Algebra.types.GRAPH:\n case Algebra.types.GROUP:\n case Algebra.types.INV:\n case Algebra.types.LINK:\n case Algebra.types.NPS:\n case Algebra.types.ONE_OR_MORE_PATH:\n case Algebra.types.ORDER_BY:\n case Algebra.types.REDUCED:\n case Algebra.types.SEQ:\n case Algebra.types.SERVICE:\n case Algebra.types.SLICE:\n case Algebra.types.ZERO_OR_MORE_PATH:\n case Algebra.types.ZERO_OR_ONE_PATH:\n case Algebra.types.COMPOSITE_UPDATE:\n case Algebra.types.DELETE_INSERT:\n case Algebra.types.LOAD:\n case Algebra.types.CLEAR:\n case Algebra.types.CREATE:\n case Algebra.types.DROP:\n case Algebra.types.ADD:\n case Algebra.types.MOVE:\n case Algebra.types.COPY:\n // Operations that do not support pushing down\n // Left-join and minus might be possible to support in the future.\n return [ false, factory.createFilter(operation, expression) ];\n }\n }\n\n /**\n * Check if the given expression is a simple equals operation with one variable and one non-literal\n * (or literal with canonical lexical form) term that can be pushed into a pattern.\n * @param expression The current expression.\n * @return The variable and term to fill into the pattern, or undefined.\n */\n public getEqualityExpressionPushableIntoPattern(\n expression: Algebra.Expression,\n ): { variable: RDF.Variable; term: RDF.Term } | undefined {\n if (expression.expressionType === Algebra.expressionTypes.OPERATOR && expression.operator === '=') {\n if (expression.args[0].expressionType === 'term' && expression.args[0].term.termType !== 'Variable' &&\n (expression.args[0].term.termType !== 'Literal' ||\n this.isLiteralWithCanonicalLexicalForm(expression.args[0].term)) &&\n expression.args[1].expressionType === 'term' && expression.args[1].term.termType === 'Variable') {\n return {\n variable: expression.args[1].term,\n term: expression.args[0].term,\n };\n }\n if (expression.args[0].expressionType === 'term' && expression.args[0].term.termType === 'Variable' &&\n expression.args[1].expressionType === 'term' && expression.args[1].term.termType !== 'Variable' &&\n (expression.args[1].term.termType !== 'Literal' ||\n this.isLiteralWithCanonicalLexicalForm(expression.args[1].term))) {\n return {\n variable: expression.args[0].term,\n term: expression.args[1].term,\n };\n }\n }\n }\n\n /**\n * Check if the given term is a literal with datatype that where all values\n * can only have one possible lexical representation.\n * In other words, no variants of values exist that should be considered equal.\n * For example: \"01\"^xsd:number and \"1\"^xsd:number will return false.\n * @param term An RDF term.\n * @protected\n */\n protected isLiteralWithCanonicalLexicalForm(term: RDF.Term): boolean {\n if (term.termType === 'Literal') {\n switch (term.datatype.value) {\n case 'http://www.w3.org/2001/XMLSchema#string':\n case 'http://www.w3.org/1999/02/22-rdf-syntax-ns#langString':\n case 'http://www.w3.org/2001/XMLSchema#normalizedString':\n case 'http://www.w3.org/2001/XMLSchema#anyURI':\n case 'http://www.w3.org/2001/XMLSchema#base64Binary':\n case 'http://www.w3.org/2001/XMLSchema#language':\n case 'http://www.w3.org/2001/XMLSchema#Name':\n case 'http://www.w3.org/2001/XMLSchema#NCName':\n case 'http://www.w3.org/2001/XMLSchema#NMTOKEN':\n case 'http://www.w3.org/2001/XMLSchema#token':\n case 'http://www.w3.org/2001/XMLSchema#hexBinary':\n return true;\n }\n }\n return false;\n }\n\n /**\n * Check if there is an overlap between the two given lists of variables.\n * @param varsA A list of variables.\n * @param varsB A list of variables.\n */\n public variablesIntersect(varsA: RDF.Variable[], varsB: RDF.Variable[]): boolean {\n return varsA.some(varA => varsB.some(varB => varA.equals(varB)));\n }\n\n /**\n * Check if all variables from the first list are included in the second list.\n * The second list may contain other variables as well.\n * @param varsNeedles A list of variables to search for.\n * @param varsHaystack A list of variables to search in.\n */\n public variablesSubSetOf(varsNeedles: RDF.Variable[], varsHaystack: RDF.Variable[]): boolean {\n return varsNeedles.length <= varsHaystack.length &&\n varsNeedles.every(varA => varsHaystack.some(varB => varA.equals(varB)));\n }\n\n /**\n * Check if an expression is simply 'false'.\n * @param expression An expression.\n */\n public isExpressionFalse(expression: Algebra.Expression): boolean {\n return (expression.term && expression.term.termType === 'Literal' && expression.term.value === 'false');\n }\n\n /**\n * Get all directly nested filter expressions.\n * As soon as a non-filter is found, it is returned as the input field.\n * @param op A filter expression.\n */\n public getNestedFilterExpressions(\n op: Algebra.Filter,\n ): { nestedExpressions: Algebra.Expression[]; input: Algebra.Operation } {\n if (op.input.type === Algebra.types.FILTER) {\n const childData = this.getNestedFilterExpressions(op.input);\n return { nestedExpressions: [ op.expression, ...childData.nestedExpressions ], input: childData.input };\n }\n return { nestedExpressions: [ op.expression ], input: op.input };\n }\n}\n\nexport interface IActorOptimizeQueryOperationFilterPushdownArgs extends IActorOptimizeQueryOperationArgs {\n /**\n * If filters should be pushed down as deep as possible.\n * If false, filters will only be pushed down if the source(s) accept them,\n * or if the filter is very selective.\n * @range {boolean}\n * @default {false}\n */\n aggressivePushdown: boolean;\n /**\n * The maximum number of full iterations across the query can be done for attempting to push down filters.\n * @default {10}\n */\n maxIterations: number;\n /**\n * If conjunctive filters should be split into nested filters before applying filter pushdown.\n * This can enable pushing down deeper.\n * @range {boolean}\n * @default {true}\n */\n splitConjunctive: boolean;\n /**\n * If nested filters should be merged into conjunctive filters after applying filter pushdown.\n * @range {boolean}\n * @default {true}\n */\n mergeConjunctive: boolean;\n /**\n * If filters should be pushed into left-joins.\n * @range {boolean}\n * @default {true}\n */\n pushIntoLeftJoins: boolean;\n /**\n * If simple equality filters should be pushed into patterns and paths.\n * This only applies to equality filters with terms that are not literals that have no canonical lexical form.\n * @range {boolean}\n * @default {true}\n */\n pushEqualityIntoPatterns: boolean;\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@comunica/actor-optimize-query-operation-filter-pushdown",
3
- "version": "4.2.0",
3
+ "version": "4.4.1",
4
4
  "description": "A filter-pushdown optimize-query-operation actor",
5
5
  "lsd:module": true,
6
6
  "license": "MIT",
@@ -41,14 +41,14 @@
41
41
  "build:components": "componentsjs-generator"
42
42
  },
43
43
  "dependencies": {
44
- "@comunica/bus-optimize-query-operation": "^4.2.0",
45
- "@comunica/context-entries": "^4.2.0",
46
- "@comunica/core": "^4.2.0",
47
- "@comunica/types": "^4.2.0",
48
- "@comunica/utils-query-operation": "^4.2.0",
44
+ "@comunica/bus-optimize-query-operation": "^4.4.0",
45
+ "@comunica/context-entries": "^4.4.1",
46
+ "@comunica/core": "^4.4.0",
47
+ "@comunica/types": "^4.4.0",
48
+ "@comunica/utils-query-operation": "^4.4.1",
49
49
  "@rdfjs/types": "*",
50
50
  "rdf-terms": "^1.11.0",
51
51
  "sparqlalgebrajs": "^4.3.8"
52
52
  },
53
- "gitHead": "94e1eacab069551590cc250074b36bce08720c4c"
53
+ "gitHead": "c5cc36caf88da31173a0969a7da88cadb7f469ac"
54
54
  }