Changes in This Release for Oracle Spatial and Graph Property Graph Developer's Guide

This topic contains the following.

Changes in Oracle Database Release 19c for Property Graph Support

The following changes apply to property graph support in Release 19c of Oracle Spatial and Graph.

Update to TinkerPop 3

The storage layer API has been updated to TinkerPop 3. Use TinkerPop 3 methods instead of Blueprints 2 methods.

For more information, see Tinkerpop 3 APIs: Differences and Other Notes.

New In-Memory Analyst REST API

See Connecting with the PGX REST API to learn about PGX-specfic REST resources. Users who want to interact with the in-memory analyst in a language other than Java can now implement their own clients.

New In-Memory Analyst APIs for Release 19c

Several new APIs are added for in-memory analyst (PGX) support in Oracle Spatial and Graph 19c.

Creating Vertex/Edge Sets from a PGQL Result Set

You can create vertex or edge sets from of a given PGQL result set. In the following example, the PGQL query selects all the vertices with values for the property age greater than 24 and then the getVertices() call creates a vertex set containing such vertices.

resultSet = g.queryPgql("SELECT x MATCH (x) WHERE x.age > 24")
vertexSet = g.getVertices(new ResultSetVertexFilter(resultSet, "x"))

This operation is executed on the PGX server when running in client-server mode and removes the need to fetch the result set to the client side in order to create a collection. This brings performance benefits for result sets of any size and enables handling very large result sets that may be troublesome to handle on a client machine.

Sharing Graphs by Name

Graphs can be shared by name, allowing you to mark graphs as shared and retrieve them from any session the graph name. You can mark graphs as shared with other sessions by calling graph.publish(), and other sessions can get a reference to the published graphs via session.getGraph("<name>"). You can see which graphs have been published by calling session.getGraphs(). The owner of a shared graph can modify its name by calling graph.rename("<name>").

Besides graphs, individual properties of a graph can be shared, too, by calling property.publish().

One implication of this feature is that all graph names must now be globally unique across sessions.

New In-Memory Analyst Built-In Algorithms

The following new built-in algorithms are included for the in-memory analyst:

  • Infomap
  • Topological Sort and Topological Schedule

Additions to PGQL Support in In-Memory Analyst for Release 19c

Several features are added to PGQL support.

Using EXISTS and NOT EXISTS Subqueries

You can express existential subqueries. For example:

SELECT a.name, b.name MATCH (a)-[:friendOf]->(b) WHERE
  EXISTS (SELECT * MATCH (a)-[:friendOf]->(c)-[:friendOf]->(b))
Using Subqueries Inside the PATH Clause

You can express a subquery in the WHERE clause of the PATH definition. The following example defines a path ending in a vertex that is not the oldest in the graph:

PATH p AS (a) -> (b) WHERE EXISTS (SELECT * MATCH (x) WHERE x.age > b.age) SELECT ...

One limitation of the current implementation is that only simple constraints (constraints accessing at most one of the pattern variables) are allowed under the WHERE clause. A query that would not be supported is:

PATH p AS (a) -> (b) WHERE EXISTS (SELECT * MATCH (a) -> (c) -> (b)) SELECT ...
Using Scalar Subqueries

You can perform scalar subqueries. For example, the following query selects all the persons whose age is greater than the average age of their friends:

SELECT a.name MATCH (a) WHERE a.age > (SELECT AVG(b.age) MATCH (a)-[:friendOf]->(b))
Other New and Changed PGQL Features for Release 19c

Other noteworthy new and changed features include the following.

  • Introduced a FROM clause for specifying an input graph.
  • The FROM clause is optional in PgxGraph#queryPgql(String), PgxGraph#preparePgql(String), and PgxGraph#explainPgql(String).
  • The FROM clause is mandatory in PgxSession#queryPgql(String), PgxSession#preparePgql(String), and PgxSession#explainPgql(String).
  • The FROM clause is not supported when executing PGQL queries against Oracle Database with OraclePgqlStatement and OraclePgqlPreparedStatement.
  • The WHERE clause from PGQL 1.0 has been split up into a MATCH clause and a WHERE clause.
  • The MATCH clause contains the graph pattern (vertices, edges and paths) while the WHERE clause in PGQL 1.1 contains only the filter predicates.
  • Common path expressions now have an optional WHERE clause for specifying filter expressions (for example, PATH connects_to AS () -[e]-> () WHERE e.status = 'OPEN' SELECT * MATCH ...).
  • Inlined filter predicates through WITH ... have been removed.
  • OO-style function-call syntax (for example, x.label() or x.id() has been replaced by functional-style syntax (for example, label(x) or id(x)).
  • OraclePgqlResultSet now extends oracle.pgql.lang.ResultSet so a common interface can be used to process PGQL results from both the in-memory analyst and Oracle Database.

Deprecation of Two-Table Support

Support for the two-table format described in Handling Property Graphs Using a Two-Tables Schema has been deprecated and will probably be removed in a future release.

Ibnstead, use the approach described in Creating Property Graph Views on an RDF Graph.

Deprecation of OraclePgqlResultSet

Starting in 19c, the oracle.pg.rdbms.OraclePgqlResultSet interface is deprecated and will probably be removed in a future release. Instead, use the standardized interface oracle.pgql.lang.ResultSet to retrieve values from a PGQL result set.

One difference between those two interfaces is that oracle.pgql.lang.ResultSet does not provide APIs to retrieve vertex and edge objects. Existing code using those interface should be changed to project IDs rather than OracleVertex and OracleEdge objects.

For example, change this code fragment that projects vertices and edges:

OraclePropertyGraph opg = ...;
OraclePgqlStatement ops = OraclePgqlExecutionFactory.createStatement(opg);
OraclePgqlResultSet rs = ops.executeQuery("SELECT v, e MATCH (v) -[e]-> () WHERE ...", "");
Iterator<OraclePgqlResult> itr = rs.getResults().iterator();
OraclePgqlResult opr = itr.next();
OracleVertex v = opr.getVertex(1);
OracleEdge e = opr.getEdge(2);

To the following:

OraclePropertyGraph opg = ...;
OraclePgqlStatement ops = OraclePgqlExecutionFactory.createStatement(opg);
ResultSet rs = ops.executeQuery("SELECT id(v) AS vid, id(e) AS eid MATCH (v) -[e]-> () WHERE ...", "");
rs.next();
OracleVertex v = opg.getVertex(rs.getLong("vid"));
OracleEdge e = opg.getEdge(rs.getLong("eid"));

Using only APIs from ResultSet will ensure that your application does not break when OraclePgqlResultSet is removed.