-
Notifications
You must be signed in to change notification settings - Fork 2
412 [SPARQL] Validate operand types in expressions #457
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
Draft
MaillPierre
wants to merge
17
commits into
feature/corese-next
Choose a base branch
from
feature/412-sparql-validate-operand-types-in-expressions
base: feature/corese-next
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Changes from all commits
Commits
Show all changes
17 commits
Select commit
Hold shift + click to select a range
73d3b2a
Adding visitor design pattern
MaillPierre 300dc0e
Polishing hierarchy for visitor
MaillPierre 0771d4d
Correcting to unit test compliance
MaillPierre b852ed1
Fixing IF argument testing
MaillPierre 669fb4d
Apply suggestions from code review
MaillPierre bda2ebd
Potential fix for pull request finding
MaillPierre d20c14d
Fix errand bracket
MaillPierre 124ec86
Fix rebase
MaillPierre f48fca6
Adding visitor design pattern
MaillPierre 819011a
Polishing hierarchy for visitor
MaillPierre 705ac5d
Correcting to unit test compliance
MaillPierre 0ab1b3f
Basic rule impl
MaillPierre 7edff14
Numeric operands
MaillPierre da6723c
Fix rebase
MaillPierre 4bd837c
Numeric and IRI operand validation rules
MaillPierre f1fe089
Fix other tests
MaillPierre c86b1f6
Fixing Copilot returns
MaillPierre File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
54 changes: 54 additions & 0 deletions
54
...inria/corese/core/next/query/impl/parser/semantic/rule/FilterArgumentsValidationRule.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,54 @@ | ||
| package fr.inria.corese.core.next.query.impl.parser.semantic.rule; | ||
|
|
||
| import fr.inria.corese.core.next.query.api.validation.QueryDiagnostic; | ||
| import fr.inria.corese.core.next.query.impl.parser.semantic.support.AbstractAstVisitor; | ||
| import fr.inria.corese.core.next.query.impl.sparql.ast.*; | ||
| import fr.inria.corese.core.next.query.impl.sparql.ast.constraint.*; | ||
|
|
||
| import java.util.ArrayList; | ||
| import java.util.List; | ||
|
|
||
| import static fr.inria.corese.core.next.query.impl.parser.semantic.support.SemanticValidationUtils.checkTermIsPotentialBoolean; | ||
|
|
||
| /** | ||
| * This rule checks the operators used in Filter asts | ||
| */ | ||
| public final class FilterArgumentsValidationRule extends AbstractSemanticValidationRule { | ||
|
|
||
| @Override | ||
| protected String getDiagnosticSource() { | ||
| return FilterArgumentsValidationRule.class.getSimpleName(); | ||
| } | ||
|
|
||
| @Override | ||
| public List<QueryDiagnostic> validate(QueryAst queryAst) { | ||
| FilterArgumentsValidationVisitor visitor = new FilterArgumentsValidationVisitor(); | ||
| queryAst.accept(visitor); | ||
| return visitor.getResult(); | ||
| } | ||
|
|
||
| private class FilterArgumentsValidationVisitor extends AbstractAstVisitor { | ||
| private final List<QueryDiagnostic> result = new ArrayList<>(); | ||
|
|
||
| public List<QueryDiagnostic> getResult() { | ||
| return result; | ||
| } | ||
|
|
||
| @Override | ||
| public void visit(PatternAst patternAst) { | ||
| if (patternAst instanceof FilterAst(TermAst operator) && !checkTermIsPotentialBoolean(operator)) { | ||
| result.add(buildIncorrectTypeDiagnostic(operator.getName(), "FILTER", "boolean")); | ||
| } | ||
| } | ||
|
|
||
| @Override | ||
| public void visit(HavingAst havingAst) { | ||
| for (TermAst condition : havingAst.conditions()) { | ||
| if (!checkTermIsPotentialBoolean(condition)) { | ||
| result.add(buildIncorrectTypeDiagnostic(condition.getName(), "HAVING", "boolean")); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
57 changes: 57 additions & 0 deletions
57
...e/core/next/query/impl/parser/semantic/rule/OperandArgumentBooleanTypeValidationRule.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,57 @@ | ||
| package fr.inria.corese.core.next.query.impl.parser.semantic.rule; | ||
|
|
||
| import fr.inria.corese.core.next.query.api.validation.QueryDiagnostic; | ||
| import fr.inria.corese.core.next.query.impl.parser.semantic.support.AbstractAstVisitor; | ||
| import fr.inria.corese.core.next.query.impl.sparql.ast.QueryAst; | ||
| import fr.inria.corese.core.next.query.impl.sparql.ast.TermAst; | ||
| import fr.inria.corese.core.next.query.impl.sparql.ast.constraint.AndAst; | ||
| import fr.inria.corese.core.next.query.impl.sparql.ast.constraint.BinaryConstraintAst; | ||
| import fr.inria.corese.core.next.query.impl.sparql.ast.constraint.BooleanNotAst; | ||
| import fr.inria.corese.core.next.query.impl.sparql.ast.constraint.OrAst; | ||
|
|
||
| import java.util.ArrayList; | ||
| import java.util.List; | ||
|
|
||
| import static fr.inria.corese.core.next.query.impl.parser.semantic.support.SemanticValidationUtils.checkTermIsPotentialBoolean; | ||
|
|
||
| public class OperandArgumentBooleanTypeValidationRule extends AbstractSemanticValidationRule { | ||
| @Override | ||
| protected String getDiagnosticSource() { | ||
| return OperandArgumentBooleanTypeValidationRule.class.getSimpleName(); | ||
| } | ||
|
|
||
| @Override | ||
| public List<QueryDiagnostic> validate(QueryAst queryAst) { | ||
| OperandBooleanArgumentTypeVisitor visitor = new OperandBooleanArgumentTypeVisitor(); | ||
| queryAst.accept(visitor); | ||
| return visitor.getResult(); | ||
| } | ||
|
|
||
| private class OperandBooleanArgumentTypeVisitor extends AbstractAstVisitor { | ||
| private final List<QueryDiagnostic> result = new ArrayList<>(); | ||
|
|
||
| public List<QueryDiagnostic> getResult() { | ||
| return result; | ||
| } | ||
|
|
||
| @Override | ||
| public void visit(TermAst termAst) { | ||
| if(termAst instanceof BooleanNotAst booleanNotAst) { | ||
| if(! checkTermIsPotentialBoolean( booleanNotAst.argument())) { | ||
| result.add(buildIncorrectTypeDiagnostic(booleanNotAst.argument().getName(), booleanNotAst.getName(), "boolean")); | ||
| } | ||
| } | ||
| if(termAst instanceof BinaryConstraintAst binaryConstraintAst) { | ||
| if(binaryConstraintAst instanceof AndAst | ||
| || binaryConstraintAst instanceof OrAst) { | ||
| if(! checkTermIsPotentialBoolean( binaryConstraintAst.getLeftArgument())) { | ||
| result.add(buildIncorrectTypeDiagnostic(binaryConstraintAst.getLeftArgument().getName(), binaryConstraintAst.getName(), "boolean")); | ||
| } | ||
| if(! checkTermIsPotentialBoolean( binaryConstraintAst.getRightArgument())) { | ||
| result.add(buildIncorrectTypeDiagnostic(binaryConstraintAst.getRightArgument().getName(), binaryConstraintAst.getName(), "boolean")); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } |
56 changes: 56 additions & 0 deletions
56
...orese/core/next/query/impl/parser/semantic/rule/OperandArgumentIRITypeValidationRule.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,56 @@ | ||
| package fr.inria.corese.core.next.query.impl.parser.semantic.rule; | ||
|
|
||
| import fr.inria.corese.core.next.query.api.validation.QueryDiagnostic; | ||
| import fr.inria.corese.core.next.query.impl.parser.semantic.support.AbstractAstVisitor; | ||
| import fr.inria.corese.core.next.query.impl.sparql.ast.QueryAst; | ||
| import fr.inria.corese.core.next.query.impl.sparql.ast.TermAst; | ||
| import fr.inria.corese.core.next.query.impl.sparql.ast.constraint.*; | ||
|
|
||
| import java.util.ArrayList; | ||
| import java.util.List; | ||
|
|
||
| import static fr.inria.corese.core.next.query.impl.parser.semantic.support.SemanticValidationUtils.checkTermIsPotentialIri; | ||
|
|
||
| /** | ||
| * Check that the comparison operand do not compare IRIs (except for the different != operator) | ||
| */ | ||
| public class OperandArgumentIRITypeValidationRule extends AbstractSemanticValidationRule { | ||
|
|
||
| @Override | ||
| protected String getDiagnosticSource() { | ||
| return OperandArgumentIRITypeValidationRule.class.getSimpleName(); | ||
| } | ||
|
|
||
| @Override | ||
| public List<QueryDiagnostic> validate(QueryAst queryAst) { | ||
| OperandIRIArgumentTypeVisitor visitor = new OperandIRIArgumentTypeVisitor(); | ||
| queryAst.accept(visitor); | ||
| return visitor.getResult(); | ||
| } | ||
|
|
||
| private class OperandIRIArgumentTypeVisitor extends AbstractAstVisitor { | ||
| private final List<QueryDiagnostic> result = new ArrayList<>(); | ||
|
|
||
| public List<QueryDiagnostic> getResult() { | ||
| return result; | ||
| } | ||
|
|
||
| @Override | ||
| public void visit(TermAst termAst) { | ||
| if(termAst instanceof BinaryConstraintAst binaryConstraintAst) { | ||
| if(binaryConstraintAst instanceof LowerThanAst | ||
| || binaryConstraintAst instanceof LowerOrEqualThanAst | ||
| || binaryConstraintAst instanceof GreaterThanAst | ||
| || binaryConstraintAst instanceof GreaterOrEqualThanAst) { | ||
| if(checkTermIsPotentialIri(binaryConstraintAst.getLeftArgument())) { | ||
| result.add(buildIncorrectTypeDiagnostic(binaryConstraintAst.getLeftArgument().getName(), binaryConstraintAst.getName(), "not an IRI")); | ||
| } | ||
| if(checkTermIsPotentialIri(binaryConstraintAst.getRightArgument())) { | ||
| result.add(buildIncorrectTypeDiagnostic(binaryConstraintAst.getRightArgument().getName(), binaryConstraintAst.getName(), "not an IRI")); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| } | ||
69 changes: 69 additions & 0 deletions
69
...e/core/next/query/impl/parser/semantic/rule/OperandArgumentNumericTypeValidationRule.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,69 @@ | ||
| package fr.inria.corese.core.next.query.impl.parser.semantic.rule; | ||
|
|
||
| import fr.inria.corese.core.next.query.api.validation.QueryDiagnostic; | ||
| import fr.inria.corese.core.next.query.impl.parser.semantic.support.AbstractAstVisitor; | ||
| import fr.inria.corese.core.next.query.impl.sparql.ast.QueryAst; | ||
| import fr.inria.corese.core.next.query.impl.sparql.ast.TermAst; | ||
| import fr.inria.corese.core.next.query.impl.sparql.ast.constraint.*; | ||
|
|
||
| import java.util.ArrayList; | ||
| import java.util.List; | ||
|
|
||
| import static fr.inria.corese.core.next.query.impl.parser.semantic.support.SemanticValidationUtils.checkTermIsPotentialNumeric; | ||
|
|
||
| /** | ||
| * Check that the operands and numeric functions use numeric arguments | ||
| */ | ||
| public final class OperandArgumentNumericTypeValidationRule extends AbstractSemanticValidationRule { | ||
|
|
||
| @Override | ||
| protected String getDiagnosticSource() { | ||
| return OperandArgumentNumericTypeValidationRule.class.getSimpleName(); | ||
| } | ||
|
|
||
| @Override | ||
| public List<QueryDiagnostic> validate(QueryAst queryAst) { | ||
| OperandNumericArgumentTypeVisitor visitor = new OperandNumericArgumentTypeVisitor(); | ||
| queryAst.accept(visitor); | ||
| return visitor.getResult(); | ||
| } | ||
|
|
||
| private class OperandNumericArgumentTypeVisitor extends AbstractAstVisitor { | ||
| private final List<QueryDiagnostic> result = new ArrayList<>(); | ||
|
|
||
| public List<QueryDiagnostic> getResult() { | ||
| return result; | ||
| } | ||
|
|
||
| @Override | ||
| public void visit(TermAst termAst) { | ||
| if (termAst instanceof UnaryConstraintAst unaryConstraintAst) { | ||
| if ( | ||
| (unaryConstraintAst instanceof AbsAst | ||
| || unaryConstraintAst instanceof CeilAst | ||
| || unaryConstraintAst instanceof FloorAst | ||
| || unaryConstraintAst instanceof RoundAst | ||
| || unaryConstraintAst instanceof UnaryMinusAst | ||
| || unaryConstraintAst instanceof UnaryPlusAst) | ||
| && !checkTermIsPotentialNumeric(unaryConstraintAst.argument())) { | ||
| result.add(buildIncorrectTypeDiagnostic(unaryConstraintAst.argument().getName(), unaryConstraintAst.getName(), "numeric")); | ||
| } | ||
| } | ||
|
|
||
| if (termAst instanceof BinaryConstraintAst binaryConstraintAst) { // Numeric only operands | ||
| if (binaryConstraintAst instanceof AddAst | ||
| || binaryConstraintAst instanceof DivideAst | ||
| || binaryConstraintAst instanceof MultiplyAst | ||
| || binaryConstraintAst instanceof SubtractAst | ||
| ) { | ||
| if (!checkTermIsPotentialNumeric(binaryConstraintAst.getLeftArgument())) { | ||
| result.add(buildIncorrectTypeDiagnostic(binaryConstraintAst.getLeftArgument().getName(), binaryConstraintAst.getName(), "numeric")); | ||
| } | ||
| if (!checkTermIsPotentialNumeric(binaryConstraintAst.getRightArgument())) { | ||
| result.add(buildIncorrectTypeDiagnostic(binaryConstraintAst.getRightArgument().getName(), binaryConstraintAst.getName(), "numeric")); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } |
104 changes: 104 additions & 0 deletions
104
...java/fr/inria/corese/core/next/query/impl/parser/semantic/support/AbstractAstVisitor.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,104 @@ | ||
| package fr.inria.corese.core.next.query.impl.parser.semantic.support; | ||
|
|
||
| import fr.inria.corese.core.next.query.impl.sparql.ast.*; | ||
|
|
||
| /** | ||
| * Default implementation for AstVisitor | ||
| */ | ||
| public abstract class AbstractAstVisitor implements AstVisitor { | ||
|
|
||
| @Override | ||
| public void visit(PatternAst ast) { | ||
|
|
||
| } | ||
|
|
||
| @Override | ||
| public void visit(QueryAst ast) { | ||
|
|
||
| } | ||
|
|
||
| @Override | ||
| public void visit(UpdateRequestUnitAst ast) { | ||
|
|
||
| } | ||
|
|
||
| @Override | ||
| public void visit(TermAst ast) { | ||
|
|
||
| } | ||
|
|
||
| @Override | ||
| public void visit(ProjectionAst ast) { | ||
|
|
||
| } | ||
|
|
||
| @Override | ||
| public void visit(QueryPrologueAst ast) { | ||
|
|
||
| } | ||
|
|
||
| @Override | ||
| public void visit(ValuesAst ast) { | ||
|
|
||
| } | ||
|
|
||
| @Override | ||
| public void visit(ValueMappingAst ast) { | ||
|
|
||
| } | ||
|
|
||
| @Override | ||
| public void visit(SolutionModifierAst ast) { | ||
|
|
||
| } | ||
|
|
||
| @Override | ||
| public void visit(GroupGraphPatternAst ast) { | ||
|
|
||
| } | ||
|
|
||
| @Override | ||
| public void visit(TriplePatternAst ast) { | ||
|
|
||
| } | ||
|
|
||
| @Override | ||
| public void visit(ConstructTemplateAst ast) { | ||
|
|
||
| } | ||
|
|
||
| @Override | ||
| public void visit(DatasetClauseAst ast) { | ||
|
|
||
| } | ||
|
|
||
| @Override | ||
| public void visit(GroupByAst ast) { | ||
|
|
||
| } | ||
|
|
||
| @Override | ||
| public void visit(HavingAst ast) { | ||
|
|
||
| } | ||
|
|
||
| @Override | ||
| public void visit(OrderConditionAst ast) { | ||
|
|
||
| } | ||
|
|
||
| @Override | ||
| public void visit(PrefixDeclarationAst ast) { | ||
|
|
||
| } | ||
|
|
||
| @Override | ||
| public void visit(ServiceAst ast) { | ||
|
|
||
| } | ||
|
|
||
| @Override | ||
| public void visit(GraphRefAst ast) { | ||
|
|
||
| } | ||
| } |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.