Issues & Decisions
...
#
...
Issue
...
Notes
...
Decision
...
Antlr changes to be made to recognize OR as input in cps-path
...
Adding OR operator to the antlr grammer file
PATH : cps-path-parser/src/main/antlr4/org/onap/cps/cpspath/parser/antlr4/CpsPath.g4
Solution : listElementRef : OB leafCondition ( ( KW_AND | KW_OR) leafCondition)* CB
multipleLeafConditions : OB leafCondition ( ( KW_AND | KW_OR) leafCondition)* CB
It is tested by antlr test
...
Code changes made to recognise the operatoe i.e., and ,or
PATH:cps-path-parser/src/main/java/org/onap/cps/cpspath/parser/CpsPathBuilder.java
Solution:
String parent = ctx.getParent().getText();
String payload = ctx.getPayload().getText();
payloads.add(payload);
String operator = findOperator(parent, payloads);
appendCondition(normalizedXpathBuilder, ctx.leafName().getText(), comparisonValue, operator);
if (processingAncestorAxis) {
appendCondition(normalizedAncestorPathBuilder, ctx.leafName().getText(), comparisonValue, operator);
}
}
private String findOperator(String parent, List<String> payloads) {
StringBuilder parentStringBuilder = new StringBuilder(parent);
try {
payloads.forEach(payload -> parentStringBuilder.delete(parentStringBuilder.indexOf(payload), parentStringBuilder.indexOf(payload) + payload.length()));
parentStringBuilder.delete(0, parentStringBuilder.indexOf("[") + 1);
return parentStringBuilder.toString().trim();
} catch (RuntimeException e) {
return null;
}
}
...
Table of Contents |
---|
References
Query data node using cps-path
In query of data node, when we can query using <,>,>=,<= comparative operators . Also we can combine “AND/OR” conditions with comparative operators . Below are the some examples
Comparative Operators Condition
# | cps-path | Output | |||||||
---|---|---|---|---|---|---|---|---|---|
1 | Using "<" condition cps-path : //books[@price<15] |
| |||||||
2 | Using "<" with OR condition cps-path : //books[@price<10 or @lang="German"] |
| |||||||
3 | Using ">" with AND condition cps-path : //books[@price>13 and @title="A Book with No Language"] |
|
currentNormalizedPathBuilder.append(name);
currentNormalizedPathBuilder.append("='");
currentNormalizedPathBuilder.append(value);
currentNormalizedPathBuilder.append("'");
}
}
PATH:cps-path-parser/src/test/groovy/org/onap/cps/cpspath/parser/CpsPathQuerySpec.groovy
1. def 'Parse cps path having OR operator containing #scenario.'() {
when: 'the given cps path is parsed'
def result = CpsPathUtil.getCpsPathQuery(cpsPath)
then: 'the query has the right normalized xpath type'
assert result.normalizedXpath == expectedNormalizedXPath
where: 'the following data is used'
scenario | cpsPath || expectedNormalizedXPath
'parent & child with more than one attribute' | '/parent/child[@key1=1 or @key2="abc"]/child2' || "/parent/child[@key1='1' or @key2='abc']/child2"
}
2. def 'Parse cps path that ends with a yang list containing #scenario and having or operator '() {
when: 'the given cps path is parsed'
def result = CpsPathQuery.createFrom(cpsPath)
then: 'the query has the right xpath type'
result.cpsPathPrefixType == DESCENDANT
and: 'the right parameters are set'
result.descendantName == "child"
result.leavesData.size() == expectedNumberOfLeaves
where: 'the following data is used'
scenario | cpsPath || expectedNumberOfLeaves
'more than one attribute' | '//child[@int-leaf=5 or @leaf-name="leaf value"]' || 2
}
Testcases in
CpsDataPersistenceQueryDataNodeSpec.groovy
def 'Cps Path query using descendant anywhere with #scenario OR condition(s) for a container element.'() {
when: 'a query is executed to get a data node by the given cps path'
def result = objectUnderTest.queryDataNodes(DATASPACE_NAME, ANCHOR_FOR_SHOP_EXAMPLE, cpsPath, OMIT_DESCENDANTS)
then: 'the correct number of data nodes are retrieved'
result.size() == expectedXPaths.size()
and: 'xpaths of the retrieved data nodes are as expected'
for (int i = 0; i < result.size(); i++) {
assert result[i].getXpath() == expectedXPaths[i]
}
where: 'the following data is used'
scenario
| |||||||||
4 | Using ">=" with combination of OR/AND condition cps-path : //books[@price>=13 or @lang="Spanish" and @title="Good Omens"] |
| |||||||
---|---|---|---|---|---|---|---|---|---|
5 | Using "<=" with combination of AND/OR condition cps-path : //books[@price<=15 and @title="Annihilation" or @lang="Spanish"] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
So, this groovy testcase is based on the Query where it as
...
|
Implementation of Comparative Operator
1.Update antlr parser to recognize <,>,<=,>= in leaf-condition
2.Implement required (native) query
3.Add Integration tests for comparative operators
4.Update documentation
5.demo to team
Query used : SELECT * FROM fragment WHERE anchor_id = :anchorId anchorId AND xpath ~ :xpathRegex AND attributes @> :leafDataAsJson\\:\\:jsonb
The problem is we are unable to find the logic how AND condition has been implemented , Also OR works as AND
In this query they are passing anchor id,xpatRegex,Attributes but no where we see either of two operators(i.e, and/or).
Here we had analysis that whatever the attributes having jsondata is taking as graphdatabase that inbuilt functions as AND
So, would like to get help with it((attributes ->> 'price')\:\:int > '13' and attributes @> '{"title":"A Book with No Language"}')
Limitations
1.Using comparative operators with string values will lead to an error at runtime. This error can't be validated earlier as the datatype is unknown until the execution phase.