orientdb icon indicating copy to clipboard operation
orientdb copied to clipboard

`$current` and `$parent` Variables Not Working in traverse Command

Open mikhalov opened this issue 6 months ago • 1 comments

OrientDB Version: 3.2.32

Java Version: 17

OS: Windows

I encountered an issue when using the traverse command in OrientDB. Specifically, the variables $current and $parent, documented as usable within the traverse command, do not work as expected. Instead of allowing traversal operations with these variables, the command fails, and OrientDB throws an error indicating that the class or variable does not exist: com.orientechnologies.orient.core.exception.OCommandExecutionException: Class $current not found DB name="dbName"

Expected Behavior:

According to the documentation, $current should refer to the current element being traversed, and it should allow for operations within the traverse command. Similarly, $parent should refer to the parent of the current element. The query should execute without errors and return the expected traversal results.

Actual Behavior:

The query fails with an error indicating that $current (or $parent when used) is not recognized as a valid variable or class. This prevents the traverse command from functioning as described in the documentation.

But it works for old API (3 test case)

Unit test for reproduction:


import com.orientechnologies.orient.core.command.OCommandRequest;
import com.orientechnologies.orient.core.db.ODatabaseDocumentInternal;
import com.orientechnologies.orient.core.db.ODatabaseSession;
import com.orientechnologies.orient.core.db.OrientDB;
import com.orientechnologies.orient.core.db.OrientDBConfig;
import com.orientechnologies.orient.core.db.document.ODatabaseDocumentTx;
import com.orientechnologies.orient.core.metadata.schema.OSchema;
import com.orientechnologies.orient.core.record.OEdge;
import com.orientechnologies.orient.core.record.OVertex;
import com.orientechnologies.orient.core.record.impl.ODocument;
import com.orientechnologies.orient.core.sql.executor.OResultSet;
import com.orientechnologies.orient.core.sql.query.OConcurrentLegacyResultSet;
import com.orientechnologies.orient.core.sql.query.OSQLSynchQuery;
import com.tinkerpop.blueprints.impls.orient.OrientGraph;
import com.tinkerpop.frames.FramedGraphFactory;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertTrue;

class OrientDBTraversalTest {

    private ODatabaseSession db;

    @BeforeEach
    public void setup() {
        final OrientDB orientDB = new OrientDB("remote:localhost", OrientDBConfig.defaultConfig());
        db = orientDB.open("test", "root", "root");
        OSchema schema = db.getMetadata().getSchema();
        if (!schema.existsClass("Person")) {
            db.command("CREATE CLASS Person EXTENDS V");
        }
        if (!schema.existsClass("Pet")) {
            db.command("CREATE CLASS Pet EXTENDS V");
        }
        if (!schema.existsClass("Owns")) {
            db.command("CREATE CLASS Owns EXTENDS E");
        }

        OVertex person = db.newVertex("Person");
        person.setProperty("name", "John Doe");
        person.save();

        OVertex pet = db.newVertex("Pet");
        pet.setProperty("name", "Buddy");
        pet.save();

        OEdge ownsEdge = person.addEdge(pet, "Owns");
        ownsEdge.save();
    }

    @Test
    void testSimplifiedTraversalQuery() {
        String query = """
                select $current as person,
                       $current.out('Owns').name as petName,
                       (traverse out('Owns') from $current)
                from (select from Person where name = 'John Doe')""";

        try (OResultSet resultSet = db.query(query)) {
            assertTrue(resultSet.hasNext());

            while (resultSet.hasNext()) {
                System.out.println(resultSet.next().toJSON());
            }
        }
    }

    @Test
    void testSimplifiedTraversalQuery1() {
        String query = """
                select $current as person,
                       $current.out('Owns').name as petName,
                       $path
                from (select from Person where name = 'John Doe')
                let $path = (traverse out('Owns') from $current)""";
        try (OResultSet resultSet = db.query(query)) {
            assertTrue(resultSet.hasNext());

            while (resultSet.hasNext()) {
                System.out.println(resultSet.next().toJSON());
            }
        }
    }

    @Test
    void oldApi() {
        final FramedGraphFactory framedGraphFactory = new FramedGraphFactory();
        String query = """
                select $current as person,
                       $current.out('Owns').name as petName,
                       $path
                from (select from Person where name = 'John Doe')
                let $path = (traverse out('Owns') from $current)""";
        final ODatabaseDocumentTx rawGraph = framedGraphFactory.create(new OrientGraph((ODatabaseDocumentInternal) db))
                .getBaseGraph()
                .getRawGraph();
        final OCommandRequest cmdQuery = rawGraph.command(new OSQLSynchQuery<ODocument>(query));
        final OConcurrentLegacyResultSet<Object> resultSet = cmdQuery.execute();
        assertTrue(resultSet.iterator().hasNext());
    }

    @AfterEach
    public void tearDown() {
        db.command("DELETE VERTEX Person");
        db.command("DELETE VERTEX Pet");
        db.command("DELETE EDGE Owns");

        db.close();
    }
}

mikhalov avatar Aug 09 '24 13:08 mikhalov