Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature/paths query #2

Draft
wants to merge 18 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 26 additions & 3 deletions lib/algebra.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as rdfjs from '@rdfjs/types';
import { Wildcard } from 'sparqljs';
import { IriTerm, VariableTerm, Wildcard } from 'sparqljs';

Check failure on line 2 in lib/algebra.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, 20.x)

Cannot find module 'sparqljs' or its corresponding type declarations.

Check failure on line 2 in lib/algebra.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, 18.x)

Cannot find module 'sparqljs' or its corresponding type declarations.

Check failure on line 2 in lib/algebra.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, 16.x)

Cannot find module 'sparqljs' or its corresponding type declarations.

Check failure on line 2 in lib/algebra.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, 18.x)

Cannot find module 'sparqljs' or its corresponding type declarations.

Check failure on line 2 in lib/algebra.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, 16.x)

Cannot find module 'sparqljs' or its corresponding type declarations.
import { Term } from '@rdfjs/types';
import { Variable, Pattern as P } from 'sparqljs';

Check failure on line 4 in lib/algebra.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, 20.x)

Cannot find module 'sparqljs' or its corresponding type declarations.

Check failure on line 4 in lib/algebra.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, 18.x)

Cannot find module 'sparqljs' or its corresponding type declarations.

Check failure on line 4 in lib/algebra.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, 16.x)

Cannot find module 'sparqljs' or its corresponding type declarations.

Check failure on line 4 in lib/algebra.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, 18.x)

Cannot find module 'sparqljs' or its corresponding type declarations.

Check failure on line 4 in lib/algebra.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, 16.x)

Cannot find module 'sparqljs' or its corresponding type declarations.

export enum types {
ALT= 'alt',
Expand Down Expand Up @@ -35,7 +36,7 @@
VALUES= 'values',
ZERO_OR_MORE_PATH= 'ZeroOrMorePath',
ZERO_OR_ONE_PATH= 'ZeroOrOnePath',

PATHS= 'paths',
COMPOSITE_UPDATE= 'compositeupdate',
DELETE_INSERT= 'deleteinsert',
LOAD= 'load',
Expand Down Expand Up @@ -63,7 +64,7 @@
export type Operation =
Ask | Expression | Bgp | Construct | Describe | Distinct | Extend | From | Filter | Graph | Group | Join | LeftJoin |
Minus | Nop | OrderBy | Path | Pattern | Project | PropertyPathSymbol | Reduced | Service | Slice | Union | Values |
Update;
Update | Paths;

export type Expression = AggregateExpression | GroupConcatExpression | ExistenceExpression | NamedExpression |
OperatorExpression | TermExpression | WildcardExpression | BoundAggregate;
Expand All @@ -84,6 +85,28 @@
type: types;
}

export interface Paths extends BaseOperation {
type: types.PATHS;
start: PathEndpoint;
end: PathEndpoint;
via: PathVia;
shortest: boolean;
cyclic: boolean;
maxLength?: number;
limit?: number;
offset?: number;
}

export interface PathEndpoint {
variable: VariableTerm;
input?: { type: 'NamedNode', value: IriTerm } | { type: 'Pattern', value: Operation };
}

export type PathVia =
{ type: 'Variable', value: VariableTerm } |
{ type: 'Path', value: PropertyPathSymbol } |
{ type: 'Pattern', value: Operation };

export interface Single extends BaseOperation
{
input: Operation;
Expand Down
35 changes: 33 additions & 2 deletions lib/factory.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import * as A from './algebra';
import * as RDF from '@rdfjs/types';
import { DataFactory } from 'rdf-data-factory';
import { DataFactory, Variable } from 'rdf-data-factory';
import { stringToTerm } from "rdf-string";
import { Wildcard } from 'sparqljs';
import { IriTerm, Wildcard, Variable as variable , Pattern, VariableTerm} from 'sparqljs';

Check failure on line 5 in lib/factory.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, 20.x)

Cannot find module 'sparqljs' or its corresponding type declarations.

Check failure on line 5 in lib/factory.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, 18.x)

Cannot find module 'sparqljs' or its corresponding type declarations.

Check failure on line 5 in lib/factory.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, 16.x)

Cannot find module 'sparqljs' or its corresponding type declarations.

Check failure on line 5 in lib/factory.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, 18.x)

Cannot find module 'sparqljs' or its corresponding type declarations.

Check failure on line 5 in lib/factory.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, 16.x)

Cannot find module 'sparqljs' or its corresponding type declarations.

export default class Factory
{
Expand All @@ -22,6 +22,37 @@
result.variable = variable;
return result;
}
createPaths(
startVar: VariableTerm,
startValue: { type: 'NamedNode', value: IriTerm } | { type: 'Pattern', value: A.Operation } | undefined,
endVar: VariableTerm,
endValue: { type: 'NamedNode', value: IriTerm } | { type: 'Pattern', value: A.Operation } | undefined,
via: A.PathVia,
shortest: boolean,
cyclic: boolean,
maxLength: number | undefined,
limit: number | undefined,
offset: number | undefined

): A.Paths {
return {
type: A.types.PATHS,
start: {
variable: startVar,
input: startValue
},
end: {
variable: endVar,
input: endValue
},
via,
shortest,
cyclic,
maxLength,
limit,
offset
};
}
createBgp (patterns: A.Pattern[]): A.Bgp { return { type: A.types.BGP, patterns }; }
createConstruct (input: A.Operation, template: A.Pattern[]): A.Construct { return { type: A.types.CONSTRUCT, input, template }; }
createDescribe (input: A.Operation, terms: (RDF.Variable | RDF.NamedNode)[]): A.Describe { return { type: A.types.DESCRIBE, input, terms }; }
Expand Down
55 changes: 54 additions & 1 deletion lib/sparql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,20 @@
PropertyPath,
Query,
SelectQuery,
PathsQuery,
ServicePattern,
Triple,
UnionPattern,
Update,
ValuePatternRow,
ValuesPattern,
Variable,
Wildcard
Wildcard,
AskQuery,
DescribeQuery,
PathVia,
PathEndpoint
} from 'sparqljs';

Check failure on line 39 in lib/sparql.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, 20.x)

Cannot find module 'sparqljs' or its corresponding type declarations.

Check failure on line 39 in lib/sparql.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, 18.x)

Cannot find module 'sparqljs' or its corresponding type declarations.

Check failure on line 39 in lib/sparql.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, 16.x)

Cannot find module 'sparqljs' or its corresponding type declarations.

Check failure on line 39 in lib/sparql.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, 18.x)

Cannot find module 'sparqljs' or its corresponding type declarations.

Check failure on line 39 in lib/sparql.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, 16.x)

Cannot find module 'sparqljs' or its corresponding type declarations.
import * as Algebra from './algebra';
import Factory from './factory';
import Util from './util';
Expand Down Expand Up @@ -108,11 +113,58 @@
case types.ADD: return translateAdd(op);
case types.MOVE: return translateMove(op);
case types.COPY: return translateCopy(op);
case types.PATHS: return translatePaths(op);
}

throw new Error(`Unknown Operation type ${op.type}`);
}

function translatePaths(op: Algebra.Paths): PathsQuery {
let via: PathVia;
if (op.via.type === 'Path') {
via = { type: 'Path', value: translatePathComponent(op.via.value) };
} else if (op.via.type === 'Variable') {
via = op.via;
} else {
via = translateOperation(op.via.value);
}
let startInput: { type: 'NamedNode', value: IriTerm } | { type: 'Pattern', value: GroupPattern } | undefined = undefined;
if (op.start.input) {
if (op.start.input.type === 'NamedNode') {
startInput = { 'type': 'NamedNode', value: op.start.input.value };
} else {
startInput = { 'type': 'Pattern', value: translateOperation(op.start.input.value) };
}
}
let endInput: { type: 'NamedNode', value: IriTerm } | { type: 'Pattern', value: GroupPattern } | undefined = undefined;
if (op.end.input) {
if (op.end.input.type === 'NamedNode') {
endInput = { 'type': 'NamedNode', value: op.end.input.value };
} else {
endInput = { 'type': 'Pattern', value: translateOperation(op.end.input.value) };
}
}
return {
type: 'query',
queryType: 'PATHS',
prefixes: {},
start: {
variable: op.start.variable,
input: startInput
},
end: {
variable: op.end.variable,
input: endInput
},
via: via,
shortest: op.shortest,
cyclic: op.cyclic,
maxLength: op.maxLength,
limit: op.limit,
offset: op.offset
};
}

function translateExpression(expr: Algebra.Expression): any
{
switch(expr.expressionType)
Expand Down Expand Up @@ -206,6 +258,7 @@

if (result.operator === 'in' || result.operator === 'notin')
result.args = [result.args[0]].concat([result.args.slice(1)]);
//result.args = [result.args[0], result.args.slice(1) as any];

return result;
}
Expand Down
54 changes: 51 additions & 3 deletions lib/sparqlAlgebra.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,15 @@
GroupPattern,
InsertDeleteOperation,
IriTerm,
// VarorIriOrListOfIris,
// ListOfIris,
LoadOperation,
Ordering,
Pattern,
PropertyPath,
Query,
SelectQuery,
PathsQuery,
SparqlQuery,
Triple,
Update,
Expand All @@ -27,7 +30,7 @@
Variable,
VariableExpression,
Wildcard
} from 'sparqljs';

Check failure on line 33 in lib/sparqlAlgebra.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, 20.x)

Cannot find module 'sparqljs' or its corresponding type declarations.

Check failure on line 33 in lib/sparqlAlgebra.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, 18.x)

Cannot find module 'sparqljs' or its corresponding type declarations.

Check failure on line 33 in lib/sparqlAlgebra.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, 16.x)

Cannot find module 'sparqljs' or its corresponding type declarations.

Check failure on line 33 in lib/sparqlAlgebra.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, 18.x)

Cannot find module 'sparqljs' or its corresponding type declarations.

Check failure on line 33 in lib/sparqlAlgebra.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, 16.x)

Cannot find module 'sparqljs' or its corresponding type declarations.
import * as Algebra from './algebra';
import Factory from './factory';
import Util from './util';
Expand Down Expand Up @@ -98,10 +101,15 @@
findAllVariables(sparql);

if (sparql.type === 'query') {
if (sparql.queryType == 'PATHS'){
res = translatePathsQuery(sparql as PathsQuery);
}
else{
// group and where are identical, having only 1 makes parsing easier, can be undefined in DESCRIBE
const group: GroupPattern = { type: 'group', patterns: sparql.where || [] };
res = translateGraphPattern(group);
res = translateAggregates(sparql, res);
}
}
else if(sparql.type === 'update') {
res = translateUpdate(sparql);
Expand Down Expand Up @@ -250,6 +258,46 @@
return inScope;
}

function translatePathsQuery(sparql: PathsQuery): Algebra.Paths
{
let via: Algebra.PathVia;
if (sparql.via.type === 'Path') {
via = { type: 'Path', value: translatePathPredicate(sparql.via.value) };
} else if (sparql.via.type === 'Variable') {
via = sparql.via;
} else {
via = { type: 'Pattern', value: translateGraphPattern(sparql.via.value) };
}
let startInput: { type: 'NamedNode', value: IriTerm } | { type: 'Pattern', value: Algebra.Operation } | undefined;
if (sparql.start.input?.type === 'NamedNode') {
startInput = sparql.start.input;
} else if (sparql.start.input?.type === 'Pattern') {
startInput = { type: 'Pattern', value: translateGraphPattern(sparql.start.input.value) };
} else {
startInput = undefined;
}
let endInput: { type: 'NamedNode', value: IriTerm } | { type: 'Pattern', value: Algebra.Operation } | undefined;
if (sparql.end.input?.type === 'NamedNode') {
endInput = sparql.end.input;
} else if (sparql.end.input?.type === 'Pattern') {
endInput = { type: 'Pattern', value: translateGraphPattern(sparql.end.input.value) };
} else {
endInput = undefined;
}
return factory.createPaths(
sparql.start.variable,
startInput,
sparql.end.variable,
endInput,
via,
sparql.shortest,
sparql.cyclic,
sparql.maxLength,
sparql.limit,
sparql.offset
);
}

function translateGraphPattern(thingy: Pattern) : Algebra.Operation
{
// 18.2.2.1
Expand Down Expand Up @@ -422,7 +470,7 @@
for (let item of items)
{
if (Util.isSimpleTerm(item))
normals.push(item);
normals.push(item as RDF.NamedNode);
else if (item.pathType === '^')
inverted.push(item.items[0] as RDF.NamedNode);
else
Expand Down Expand Up @@ -648,9 +696,9 @@
const E: VariableExpression[] = [];

const A: NodeJS.Dict<AggregateExpression> = {};
select.variables = select.variables && select.variables.map(val => mapAggregate(val, A));

Check failure on line 699 in lib/sparqlAlgebra.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, 20.x)

Parameter 'val' implicitly has an 'any' type.

Check failure on line 699 in lib/sparqlAlgebra.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, 18.x)

Parameter 'val' implicitly has an 'any' type.

Check failure on line 699 in lib/sparqlAlgebra.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, 16.x)

Parameter 'val' implicitly has an 'any' type.

Check failure on line 699 in lib/sparqlAlgebra.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, 18.x)

Parameter 'val' implicitly has an 'any' type.

Check failure on line 699 in lib/sparqlAlgebra.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, 16.x)

Parameter 'val' implicitly has an 'any' type.
select.having = select.having && select.having.map(val => mapAggregate(val, A));

Check failure on line 700 in lib/sparqlAlgebra.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, 20.x)

Parameter 'val' implicitly has an 'any' type.

Check failure on line 700 in lib/sparqlAlgebra.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, 18.x)

Parameter 'val' implicitly has an 'any' type.

Check failure on line 700 in lib/sparqlAlgebra.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, 16.x)

Parameter 'val' implicitly has an 'any' type.

Check failure on line 700 in lib/sparqlAlgebra.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, 18.x)

Parameter 'val' implicitly has an 'any' type.

Check failure on line 700 in lib/sparqlAlgebra.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, 16.x)

Parameter 'val' implicitly has an 'any' type.
select.order = select.order && select.order.map(val => mapAggregate(val, A));

Check failure on line 701 in lib/sparqlAlgebra.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, 20.x)

Parameter 'val' implicitly has an 'any' type.

Check failure on line 701 in lib/sparqlAlgebra.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, 18.x)

Parameter 'val' implicitly has an 'any' type.

Check failure on line 701 in lib/sparqlAlgebra.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, 16.x)

Parameter 'val' implicitly has an 'any' type.

Check failure on line 701 in lib/sparqlAlgebra.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, 18.x)

Parameter 'val' implicitly has an 'any' type.

Check failure on line 701 in lib/sparqlAlgebra.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, 16.x)

Parameter 'val' implicitly has an 'any' type.

// if there are any aggregates or if we have a groupBy (both result in a GROUP)
if (select.group || Object.keys(A).length > 0)
Expand Down Expand Up @@ -790,7 +838,7 @@
if ('expression' in thingy && thingy.expression)
return { ...thingy, expression: mapAggregate(thingy.expression, aggregates) };
if ('args' in thingy && thingy.args)
return { ...thingy, args: thingy.args.map(subthingy => mapAggregate(subthingy, aggregates)) };
return { ...thingy, args: thingy.args.map((subthingy: any) => mapAggregate(subthingy, aggregates)) };

// Normal variable/wildcard
return thingy;
Expand Down Expand Up @@ -837,9 +885,9 @@
let insertTriples: Algebra.Pattern[] = [];
let where: Algebra.Operation;
if (thingy.delete)
deleteTriples = Util.flatten(thingy.delete.map(input => translateUpdateTriplesBlock(input, thingy.graph)));

Check failure on line 888 in lib/sparqlAlgebra.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, 20.x)

Parameter 'input' implicitly has an 'any' type.

Check failure on line 888 in lib/sparqlAlgebra.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, 18.x)

Parameter 'input' implicitly has an 'any' type.

Check failure on line 888 in lib/sparqlAlgebra.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, 16.x)

Parameter 'input' implicitly has an 'any' type.

Check failure on line 888 in lib/sparqlAlgebra.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, 18.x)

Parameter 'input' implicitly has an 'any' type.

Check failure on line 888 in lib/sparqlAlgebra.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, 16.x)

Parameter 'input' implicitly has an 'any' type.
if (thingy.insert)
insertTriples = Util.flatten(thingy.insert.map(input => translateUpdateTriplesBlock(input, thingy.graph)));

Check failure on line 890 in lib/sparqlAlgebra.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, 20.x)

Parameter 'input' implicitly has an 'any' type.

Check failure on line 890 in lib/sparqlAlgebra.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, 18.x)

Parameter 'input' implicitly has an 'any' type.

Check failure on line 890 in lib/sparqlAlgebra.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, 16.x)

Parameter 'input' implicitly has an 'any' type.

Check failure on line 890 in lib/sparqlAlgebra.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, 18.x)

Parameter 'input' implicitly has an 'any' type.

Check failure on line 890 in lib/sparqlAlgebra.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest, 16.x)

Parameter 'input' implicitly has an 'any' type.
if (thingy.where && thingy.where.length > 0) {
where = translateGraphPattern({ type: 'group', patterns: thingy.where });
// Wrong typings, see test "using" in Sparql.js
Expand Down Expand Up @@ -875,7 +923,7 @@
{
let source: 'DEFAULT' | 'NAMED' | 'ALL' | RDF.NamedNode;
if (Util.isSimpleTerm(thingy.graph))
source = thingy.graph;
source = thingy.graph as RDF.NamedNode;
else if (thingy.graph.all)
source = 'ALL';
else if (thingy.graph.default)
Expand Down
20 changes: 19 additions & 1 deletion lib/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -180,9 +180,11 @@ export default class Util
return;

let recurseOp = (op: A.Operation) => Util.recurseOperation(op, callbacks);

switch (result.type)
{
case types.PATHS:
break
case types.ALT:
result.input.map(recurseOp);
break;
Expand Down Expand Up @@ -351,6 +353,21 @@ export default class Util

return result;
}
if (result.type === types.PATHS) {
result = factory.createPaths(
result.start.variable,
result.start.input,
result.end.variable,
result.end.input,
result.via,
result.shortest,
result.cyclic,
result.maxLength,
result.limit,
result.offset
);
}
else{

let mapOp = (op: A.Operation) => Util.mapOperation(op, callbacks, factory);

Expand Down Expand Up @@ -493,6 +510,7 @@ export default class Util
break;
default: throw new Error(`Unknown Operation type ${(result as any).type}`);
}
}

// Inherit metadata
if (toCopyMetadata) {
Expand Down
Loading
Loading