neo4j-labs / neo4rs

Neo4j driver for rust

Home Page:https://docs.rs/neo4rs

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Is array and map results supported by the library?

trentG92 opened this issue · comments

I am currently using neo4rs v0.7.0-rc.2.

For any query that returns either an array or a map I am getting a deserialization error similar to the following: "PULL: Err(DeserializationError(Other("invalid utf-8 sequence of 1 bytes from index 25"

The code running is similar to the following:

let query_string = "MATCH (f: Foo) RETURN COLLECT(f) AS foos"
let mut stream = match graph.execute(query(query_string)).await
        {
            Ok(stream) => stream,
            Err(err) => { .. }
        };
        match stream.next().await {
            Ok(Some(row)) => { .. },
            Ok(None) => { .. },
            Err(err) => { // The error is captured here }
        }

I have had a look through the documentation and there doesnt appear to be anything to indicate that this style of query is not supported.

While this example works fine if I dont collect and instead return a number of rows via "RETURN f", it doesn't work when the row is a Map for example "RETURN { bar: f.name }", I get the same sort of error, just a different index

Im not sure if this is helpful or not but I have been playing around with a test for this:

let neo4j = container::Neo4jContainer::new().await;
    let graph = neo4j.graph();

    let arr_size = 500;

    let name = "aaabbbcccdddeeefffggg";
    println!("Size: {} bytes", name.bytes().len());

    let names: Vec<String> = (1..=arr_size).map(|_| name.to_string()).collect();

    graph
        .run(
            query("UNWIND $names AS n CREATE (p: Person { name: n})")
                .param("names", names.as_slice()),
        )
        .await
        .unwrap();

    let mut result = graph
        .execute(query("MATCH (p:Person) RETURN COLLECT(p.name) AS people"))
        .await
        .unwrap();
    let row = result.next().await.unwrap().unwrap();
    let people = row.get::<Vec<String>>("people").unwrap();
    assert_eq!(people.len(), arr_size);

The weird result I am getting is that the bytes being read in connection.recv is odd. There are these strange fragments that I am not able to explain myself. As I would expect, the bytes look something like this:

\xb1q\x91\xd5\x01\xc2\xd0\x15aaabbbcccdddeeefffggg\xd0\x15aaabbbcccdddeeefffggg

The expected a through g triples repeat separated by the \xd0\x15 bytes. However there is one, single different entry,

aaabbbcccdddeeeffgg\xd0\x15

note the double and not triple "ffgg". This is also reproduced on every subsequent rerun of the test.
I didnt understand what was happening so I tried again with only 450 entries. This has many more strange entries every 10 or so:

"aaabbbcccdddegeefffggg"
"aaabbbcccddgdeeefffggg"
"aaabbbcccgdddeeefffggg"
"aaabbbcgccdddeeefffggg"

The strange thing on this second run is the almost regular substitution pattern occurring.

Like I said, at this stage I am unsure what the problem is here. While this is occuring against a neo4j test container, this is occurring also against a memgraph instance I am working against. That leads me to believe that it might originate on the server implementations via packstream or something?

If its any help at all this is the issue that started all this for me. Excuse the medical terms but this is the expected strings

"enterocolitis",
"intraventricular hemorrhage",
"hematological abnormalities",

Printing out the bytes right before the call to from_utf8 in the parse implementation on BoltString, this is the associated output

b"enterocolitis"
b"intraventricular hemorrhage"
b"hematologicaabnormalities\xd0\x1a"

The resultset this occurs in is about 560 entries in the array, and this is around the 450th position in the array. This is similar to my first repeatable result in my last post.

I am currently releasing 0.7.0-rc.3 which includes #151 that could fix this issue. Could you verify once the version is available?

I can confirm that #151 does resolve these. Would you like me to add the few tests I have written via pull request?

Yes, that would be great, thank you!