Changing the generated query to support projection

This commit is contained in:
luca.frosini 2023-11-16 12:02:17 +01:00
parent 2d863b99fc
commit e0bfef4c49
17 changed files with 172 additions and 29 deletions

View File

@ -10,6 +10,9 @@ import org.gcube.informationsystem.types.PropertyTypeName.BaseTypeGroup;
/**
* @author Luca Frosini (ISTI - CNR)
* See https://www.orientdb.com/docs/3.0.x/sql/SQL-Where.html
* https://www.orientdb.com/docs/3.0.x/sql/SQL-Syntax.html#conditions
* https://www.orientdb.com/docs/3.0.x/sql/SQL-Syntax.html#comparison-operators
* https://www.orientdb.com/docs/3.0.x/sql/SQL-Syntax.html#boolean-operators
*/
public enum ConditionalOperator {
@ -19,22 +22,25 @@ public enum ConditionalOperator {
LT("_lt", " < ", BaseTypeGroup.ANY, "Matches values that are less than a specified value."),
LTE("_lte", " <= ", BaseTypeGroup.ANY, "Matches values that are less than or equal to a specified value."),
NE("_ne", " <> ", BaseTypeGroup.ANY, "Matches all values that are not equal to a specified value."),
BETWEEN("_between", " BETWEEN ", BaseTypeGroup.ANY, "The value is between a range. E.g. `price BETWEEN 10 AND 30`. It's equivalent to `price >= 10 AND price <= 30`."),
BETWEEN("_between", " BETWEEN %s AND %s", BaseTypeGroup.ANY, "Returns TRUE is a value is between two values, eg. 5 BETWEEN 1 AND 10. The value is between a range. E.g. `price BETWEEN 10 AND 30`. It's equivalent to `price >= 10 AND price <= 30`."),
IS("_is", " IS ", BaseTypeGroup.ANY, "Used to test if a value is NULL"),
LIKE("_like", " LIKE ", BaseTypeGroup.STRING, "Similar to equals, but allow the wildcard '%' that means 'any'. E.g. `name LIKE 'Luk%'`"),
LIKE("_like", " LIKE ", BaseTypeGroup.STRING, "For strings, checks if a string contains another string. % is used as a wildcard, eg. 'foobar CONTAINS '%ooba%''. Similar to equals, but allow the wildcard '%' that means 'any'. E.g. `name LIKE 'Luk%'`"),
CONTAINS_TEXT("_containsText", " CONTAINSTEXT ", BaseTypeGroup.STRING, "The string contains such text. E.g. `text CONTAINSTEXT 'jay'`"),
MATCHES("_matches", " MATCHES ", BaseTypeGroup.STRING, "Matches the string using a Regular Expression. E.g. `text MATCHES '\b[A-Z0-9.%+-]+@[A-Z0-9.-]+.[A-Z]{2,4}\b'`"),
MATCHES("_matches", " MATCHES ", BaseTypeGroup.STRING, "Checks if a string matches a regular expression. Matches the string using a Regular Expression. E.g. `text MATCHES '\b[A-Z0-9.%+-]+@[A-Z0-9.-]+.[A-Z]{2,4}\b'`"),
IN("_in", " IN ", BaseTypeGroup.COLLECTION, "Matches any of the values specified in an array. E.g. `name in ['European','Asiatic']`"),
CONTAINS("_contains", " CONTAINS ", BaseTypeGroup.COLLECTION, "True if the collection contains at least one element that satisfy the next condition. Condition can be a single item: in this case the behaviour is like the IN operator. E.g. `children contains (name = 'Luke')` - `map.values() contains (name = 'Luke')`"),
IN("_in", " IN ", BaseTypeGroup.COLLECTION, "The same as CONTAINS, but with inverted operands. Matches any of the values specified in an array. E.g. `name in ['European','Asiatic']`"),
CONTAINS("_contains", " CONTAINS ", BaseTypeGroup.COLLECTION, "Checks if the left collection contains the right element. The left argument has to be a colleciton, otherwise it returns FALSE. It's NOT the check of colleciton intersections, so ['a', 'b', 'c'] CONTAINS ['a', 'b'] will return FALSE, while ['a', 'b', 'c'] CONTAINS 'a' will return TRUE. True if the collection contains at least one element that satisfy the next condition. Condition can be a single item: in this case the behaviour is like the IN operator. E.g. `children contains (name = 'Luke')` - `map.values() contains (name = 'Luke')`"),
CONTAINS_ALL("_containsAll", " CONTAINSALL ", BaseTypeGroup.COLLECTION, "True if all the elements of the collection satisfy the next condition. E.g. `children CONTAINSALL (name = 'Luke')`"),
CONTAINS_ANY("_containsAny", " CONTAINSANY ", BaseTypeGroup.COLLECTION, "True if all the elements of the collection satisfy the next condition. E.g. `children CONTAINSANY (name = 'Luke')`"),
CONTAINS_KEY("_containsKey", " CONTAINSKEY ", BaseTypeGroup.MAP, "True if the map contains at least one key equals to the requested. You can also use map.keys() CONTAINS in place of it. E.g. `connections CONTAINSKEY 'Luke'`"),
CONTAINS_VALUE("_containsValue", " CONTAINSVALUE ", BaseTypeGroup.MAP , "True if the map contains at least one value equals to the requested. You can also use map.values() CONTAINS in place of it. E.g. `connections containsValue 10:3`");
CONTAINS_KEY("_containsKey", " CONTAINSKEY ", BaseTypeGroup.MAP, "For maps, the same as for CONTAINS, but checks on the map keys. True if the map contains at least one key equals to the requested. You can also use map.keys() CONTAINS in place of it. E.g. `connections CONTAINSKEY 'Luke'`"),
CONTAINS_VALUE("_containsValue", " CONTAINSVALUE ", BaseTypeGroup.MAP , "For maps, the same as for CONTAINS, but checks on the map values. True if the map contains at least one value equals to the requested. You can also use map.values() CONTAINS in place of it. E.g. `connections containsValue 10:3`"),
IS_DEFINED("_isDefined", " IS DEFINED ", BaseTypeGroup.ANY, "Returns TRUE is a field is defined in a document"),
IS_NOT_DEFINED("_isNotDefined", " IS NOT DEFINED ", BaseTypeGroup.ANY, "Returns TRUE is a field is not defined in a document");
protected final String operator;
protected final String conditionalOperator;
protected final BaseTypeGroup allowed;

View File

@ -0,0 +1,29 @@
package org.gcube.informationsystem.resourceregistry.queries.operators;
/**
* @author Luca Frosini (ISTI - CNR)
*
* Methods: also called "Field Operators"
*
* SQL Methods are similar to SQL functions but they apply to values.
* In Object Oriented paradigm they are called "methods", as functions related to a class.
* So what's the difference between a function and a method?
*
* This is a SQL function:
*
* SELECT sum( salary ) FROM employee
*
* This is a SQL method:
*
* SELECT salary.toJSON() FROM employee
*
* As you can see the method is executed against a field/value.
* Methods can receive parameters, like functions.
* You can concatenate N operators in sequence.
*
* See https://orientdb.com/docs/3.0.x/sql/SQL-Where.html#methods
* http://orientdb.com/docs/3.0.x/sql/SQL-Methods.html
*/
public enum FieldOperator {
}

View File

@ -0,0 +1,9 @@
package org.gcube.informationsystem.resourceregistry.queries.operators;
/**
* @author Luca Frosini (ISTI - CNR)
* See https://www.orientdb.com/docs/3.0.x/sql/SQL-Functions.html
*/
public class Function {
}

View File

@ -7,7 +7,16 @@ import java.util.Set;
/**
* @author Luca Frosini (ISTI - CNR)
* See https://www.orientdb.com/docs/3.0.x/sql/SQL-Where.html
*
* OrientDB supports the eval() function to execute complex operations. Example:
*
* SELECT eval( "amount * 120 / 100 - discount" ) as finalPrice from Order
*
* See https://www.orientdb.com/docs/3.0.x/sql/SQL-Where.html#mathematics-operators
* https://www.orientdb.com/docs/3.0.x/sql/SQL-Syntax.html#math-operators
* https://www.orientdb.com/docs/3.0.x/sql/SQL-Syntax.html#math-operators-precedence
* https://www.orientdb.com/docs/3.0.x/sql/SQL-Syntax.html#array-concatenation
*/
public enum MatemathicsOperator {

View File

@ -81,7 +81,7 @@ public class JsonQueryTest extends ContextTest {
@Test
public void testSingleCreateQuery() throws Exception {
File queriesDirectory = getQueriesDirectory();
File jsonQueryFile = new File(queriesDirectory, "query9.json");
File jsonQueryFile = new File(queriesDirectory, "query10.json");
ObjectMapper objectMapper = new ObjectMapper();
JsonNode jsonNode = objectMapper.readTree(jsonQueryFile);
logger.info("Going to test the following JSON query {}", jsonNode.toString());
@ -107,8 +107,8 @@ public class JsonQueryTest extends ContextTest {
String result = jsonQuery.query();
logger.info("Result : {}", result);
}
public List<Entity> testSingleQuery(int offset, int limit) throws Exception {
protected List<Entity> testSingleQuery(int offset, int limit) throws Exception {
ContextTest.setContextByName(DEVVRE);
File queriesDirectory = getQueriesDirectory();
File jsonQueryFile = new File(queriesDirectory, "query1.json");

View File

@ -0,0 +1,10 @@
SELECT EXPAND(eservice) FROM (
MATCH
{class: EService, as: eservice, where: ($currentMatch['@class'] INSTANCEOF 'EService')}
.outE('IsIdentifiedBy').inV("SoftwareFacet") {where: (($currentMatch['@class'] INSTANCEOF 'SoftwareFacet') AND name='data-transfer-service' AND group='DataTransfer')}
.inE('IsIdentifiedBy').outV('Eservice') {where: ($matched.eservice == $currentMatch)}
.outE('ConsistsOf') {where: (propagationConstraint.add='propagate')}
.inV("StateFacet") {where: (($currentMatch['@class'] INSTANCEOF 'StateFacet') AND value="down")}
RETURN
eservice
)

View File

@ -18,9 +18,9 @@ SELECT FROM (
TRAVERSE inV("EService") FROM (
SELECT FROM (
TRAVERSE outE("Activates") FROM (
SELECT FROM HostingNode WHERE id = "5fbc1a56-d450-4f0f-85c1-9b1684581717"
SELECT FROM HostingNode WHERE id = "44fac329-eed5-4f18-90ba-a54d5aad316e"
)
) WHERE id = "d3f58e52-5346-47bc-b736-9d77a0b554ce"
) WHERE id = "bd89a311-780d-4efe-93e5-08281e53bce7"
)
)
)
@ -35,7 +35,7 @@ SELECT FROM (
)
)
)
) WHERE endpoint = "http://pc-frosini.isti.cnr.it:8080/data-transfer-service/gcube/service"
) WHERE endpoint = "http://smartexecutor1.dev.int.d4science.net:80/data-transfer-service/gcube/resource"
)
)
) WHERE @class INSTANCEOF "EService"

View File

@ -23,17 +23,17 @@
"type": "ConsistsOf",
"target": {
"type": "AccessPointFacet",
"endpoint": "http://pc-frosini.isti.cnr.it:8080/data-transfer-service/gcube/service"
"endpoint": "http://smartexecutor1.dev.int.d4science.net:80/data-transfer-service/gcube/resource"
}
}
],
"isRelatedTo" : [
{
"type": "Activates",
"id": "d3f58e52-5346-47bc-b736-9d77a0b554ce",
"id": "bd89a311-780d-4efe-93e5-08281e53bce7",
"source": {
"type": "HostingNode",
"id" : "5fbc1a56-d450-4f0f-85c1-9b1684581717"
"id" : "44fac329-eed5-4f18-90ba-a54d5aad316e"
}
}
]

View File

@ -0,0 +1,15 @@
SELECT EXPAND(eservice) FROM (
MATCH
{class: EService, as: eservice, where: ($currentMatch['@class'] INSTANCEOF 'EService')}
.outE('IsIdentifiedBy').inV("SoftwareFacet") {where: (($currentMatch['@class'] INSTANCEOF 'SoftwareFacet') AND name='data-transfer-service' AND group='DataTransfer')}
.inE('IsIdentifiedBy').outV('Eservice') {where: ($matched.eservice == $currentMatch)}
.outE('ConsistsOf') {where: (propagationConstraint.add='propagate')}
.inV("StateFacet") {where: (($currentMatch['@class'] INSTANCEOF 'StateFacet') AND value="down")}
.inE('ConsistsOf').outV('Eservice') {where: ($matched.eservice == $currentMatch)}
.outE('ConsistsOf').inV("AccessPointFacet") {where: (($currentMatch['@class'] INSTANCEOF 'AccessPointFacet') AND endpoint="http://smartexecutor1.dev.int.d4science.net:80/data-transfer-service/gcube/resource")}
.inE('ConsistsOf').outV('Eservice') {where: ($matched.eservice == $currentMatch)}
.inE('Activates') {where: (id='bd89a311-780d-4efe-93e5-08281e53bce7')}
.outV("HostingNode") {where: (id='44fac329-eed5-4f18-90ba-a54d5aad316e')}
RETURN
eservice
)

View File

@ -1 +1 @@
SELECT FROM ( TRAVERSE outV("EService") FROM ( TRAVERSE inE("ConsistsOf") FROM ( SELECT FROM ( TRAVERSE inV("AccessPointFacet") FROM ( TRAVERSE outE("ConsistsOf") FROM ( TRAVERSE outV("EService") FROM ( TRAVERSE inE("IsIdentifiedBy") FROM ( SELECT FROM ( TRAVERSE inV("SoftwareFacet") FROM ( TRAVERSE outE("IsIdentifiedBy") FROM ( TRAVERSE outV("EService") FROM ( SELECT FROM ( TRAVERSE inE("ConsistsOf") FROM ( SELECT FROM ( TRAVERSE inV("StateFacet") FROM ( TRAVERSE outE("ConsistsOf") FROM ( TRAVERSE inV("EService") FROM ( SELECT FROM ( TRAVERSE outE("Activates") FROM ( SELECT FROM HostingNode WHERE id = "5fbc1a56-d450-4f0f-85c1-9b1684581717")) WHERE id = "d3f58e52-5346-47bc-b736-9d77a0b554ce")))) WHERE value = "down")) WHERE propagationConstraint.add = "propagate")))) WHERE name = "data-transfer-service" AND group = "DataTransfer"))))) WHERE endpoint = "http://pc-frosini.isti.cnr.it:8080/data-transfer-service/gcube/service"))) WHERE @class INSTANCEOF "EService"
SELECT FROM ( TRAVERSE outV("EService") FROM ( TRAVERSE inE("ConsistsOf") FROM ( SELECT FROM ( TRAVERSE inV("AccessPointFacet") FROM ( TRAVERSE outE("ConsistsOf") FROM ( TRAVERSE outV("EService") FROM ( TRAVERSE inE("IsIdentifiedBy") FROM ( SELECT FROM ( TRAVERSE inV("SoftwareFacet") FROM ( TRAVERSE outE("IsIdentifiedBy") FROM ( TRAVERSE outV("EService") FROM ( SELECT FROM ( TRAVERSE inE("ConsistsOf") FROM ( SELECT FROM ( TRAVERSE inV("StateFacet") FROM ( TRAVERSE outE("ConsistsOf") FROM ( TRAVERSE inV("EService") FROM ( SELECT FROM ( TRAVERSE outE("Activates") FROM ( SELECT FROM HostingNode WHERE id = "44fac329-eed5-4f18-90ba-a54d5aad316e")) WHERE id = "bd89a311-780d-4efe-93e5-08281e53bce7")))) WHERE value = "down")) WHERE propagationConstraint.add = "propagate")))) WHERE name = "data-transfer-service" AND group = "DataTransfer"))))) WHERE endpoint = "http://smartexecutor1.dev.int.d4science.net:80/data-transfer-service/gcube/resource"))) WHERE @class INSTANCEOF "EService"

View File

@ -0,0 +1,32 @@
SELECT EXPAND(eservice) FROM (
MATCH
{class: EService, as: eservice, where: ($currentMatch['@class'] INSTANCEOF 'EService')}
.outE('IsIdentifiedBy').inV("SoftwareFacet") {where: (($currentMatch['@class'] INSTANCEOF 'SoftwareFacet') AND name='data-transfer-service' AND group='DataTransfer')}
.inE('IsIdentifiedBy').outV('Eservice') {where: ($matched.eservice == $currentMatch)}
.outE('ConsistsOf') {where: (propagationConstraint.add='propagate')}
.inV("StateFacet") {where: (($currentMatch['@class'] INSTANCEOF 'StateFacet') AND value="down")}
.inE('ConsistsOf').outV('Eservice') {where: ($matched.eservice == $currentMatch)}
.outE('ConsistsOf').inV("AccessPointFacet") {where: (($currentMatch['@class'] INSTANCEOF 'AccessPointFacet') AND endpoint="http://smartexecutor1.dev.int.d4science.net:80/data-transfer-service/gcube/resource")}
.inE('ConsistsOf').outV('Eservice') {where: ($matched.eservice == $currentMatch)}
.inE('Activates').outV("HostingNode").outE('ConsistsOf').inV("CPUFacet") {where: (vendor='GenuineIntel')}
RETURN
eservice
)
SELECT EXPAND(ret) FROM (
MATCH
{class: EService, as: eservice, where: ($currentMatch['@class'] INSTANCEOF 'EService')}
.outE('IsIdentifiedBy').inV("SoftwareFacet") {where: (($currentMatch['@class'] INSTANCEOF 'SoftwareFacet') AND name='data-transfer-service' AND group='DataTransfer')}
.inE('IsIdentifiedBy').outV('Eservice') {where: ($matched.eservice == $currentMatch)}
.outE('ConsistsOf') {where: (propagationConstraint.add='propagate')}
.inV("StateFacet") {where: (($currentMatch['@class'] INSTANCEOF 'StateFacet') AND value="ready")}
.inE('ConsistsOf').outV('Eservice') {where: ($matched.eservice == $currentMatch)}
.outE('ConsistsOf').inV("AccessPointFacet") {where: (($currentMatch['@class'] INSTANCEOF 'AccessPointFacet') AND endpoint="http://smartexecutor1.dev.int.d4science.net:80/data-transfer-service/gcube/resource")}
.inE('ConsistsOf').outV('Eservice') {where: ($matched.eservice == $currentMatch)}
.inE('Activates').outV("HostingNode").outE('ConsistsOf').inV("CPUFacet") {where: (($currentMatch['@class'] INSTANCEOF 'CPUFacet') AND vendor='GenuineIntel')}
RETURN
DISTINCT(eservice) as ret
)

View File

@ -0,0 +1,7 @@
SELECT FROM (
TRAVERSE inV("StateFacet") FROM (
TRAVERSE outE("ConsistsOf") FROM (
SELECT FROM EService WHERE id = "93995af0-4f95-4816-a53e-3e1bc27ef475"
)
)
) WHERE value = "down" AND @class INSTANCEOF "StateFacet"

View File

@ -5,7 +5,7 @@
"type": "ConsistsOf",
"source" : {
"type" : "EService",
"id": "0255b7ec-e3da-4071-b456-9a2907ece1db"
"id": "93995af0-4f95-4816-a53e-3e1bc27ef475"
}
}
}

View File

@ -0,0 +1,7 @@
SELECT EXPAND(ret) FROM (
MATCH
{class: StateFacet, as: statefacet, where: (($currentMatch['@class'] INSTANCEOF 'StateFacet') AND value='down')}
.inE('ConsistsOf').outV('Eservice') {where: (($currentMatch['@class'] INSTANCEOF 'EService') AND id='93995af0-4f95-4816-a53e-3e1bc27ef475')}
RETURN
DISTINCT(statefacet) as ret
)

View File

@ -1 +1 @@
SELECT FROM ( TRAVERSE inV("StateFacet") FROM ( TRAVERSE outE("ConsistsOf") FROM ( SELECT FROM EService WHERE id = "0255b7ec-e3da-4071-b456-9a2907ece1db"))) WHERE value = "down" AND @class INSTANCEOF "StateFacet"
SELECT FROM ( TRAVERSE inV("StateFacet") FROM ( TRAVERSE outE("ConsistsOf") FROM ( SELECT FROM EService WHERE id = "93995af0-4f95-4816-a53e-3e1bc27ef475"))) WHERE value = "down" AND @class INSTANCEOF "StateFacet"

View File

@ -0,0 +1,11 @@
SELECT FROM (
TRAVERSE inV("StateFacet") FROM (
TRAVERSE outE("ConsistsOf") FROM (
SELECT FROM EService WHERE (
(id = "93995af0-4f95-4816-a53e-3e1bc27ef475" AND metadata.createdBy <> "luca.frosini")
OR
(id = "bd4402a0-2b72-41c5-a970-321343649e7d" AND metadata.createdBy = "DataTransfer:data-transfer-service:smartexecutor1.dev.int.d4science.net_80")
)
)
)
) WHERE value = "down" AND @class INSTANCEOF "StateFacet"

View File

@ -6,15 +6,23 @@
"source" : {
"type" : "EService",
"_or": [
{"_and": {
"id" : "aec0ef31-c735-4a4c-b2f4-57dfbd2fe925",
"metadata" :{ "createdBy": {"_ne": "luca.frosini"} }
}},
{"_and": {
"id" : "0255b7ec-e3da-4071-b456-9a2907ece1db",
"metadata" : { "createdBy": "DataTransfer:data-transfer-service:pc-frosini.isti.cnr.it_8080" }
}}
{
"_and": {
"id" : "93995af0-4f95-4816-a53e-3e1bc27ef475",
"metadata" : {
"createdBy": {"_ne": "luca.frosini"}
}
}
},
{
"_and": {
"id" : "bd4402a0-2b72-41c5-a970-321343649e7d",
"metadata" : {
"createdBy": "DataTransfer:data-transfer-service:smartexecutor1.dev.int.d4science.net_80"
}
}
}
]
}
}
}
}