You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@age.apache.org by GitBox <gi...@apache.org> on 2022/05/24 06:28:19 UTC
[GitHub] [incubator-age] lnoir opened a new issue, #221: AGE driver unable to handle nested array in result set
lnoir opened a new issue, #221:
URL: https://github.com/apache/incubator-age/issues/221
Hi all,
I have a query that collects and consolidates various bits of data into a derived object, but it seems to cause a problem for the AGE driver (NodeJS). Below is a contrived example you can use to replicate the issue.
## Setup
```
SELECT * FROM ag_catalog.create_graph('nesteddemo');
SELECT create_vlabel('nesteddemo','Building');
SELECT create_vlabel('nesteddemo','User');
SELECT create_vlabel('nesteddemo','Comestible');
SELECT create_elabel('nesteddemo','likes');
SELECT create_elabel('nesteddemo','lives_in');
SELECT * FROM ag_catalog.cypher('nesteddemo', $$
CREATE (b1:Building {id: "b001", name: 'Building One'})
CREATE (b2:Building {id: "b002", name: 'Building Two'})
CREATE (u1:User {id: "u001", name: 'User One'})
CREATE (u2:User {id: "u002", name: 'User Two'})
CREATE (u3:User {id: "u003", name: 'User Three'})
CREATE (p1:Comestible {name: 'Pizza', flavour: 'Pepperoni'})
CREATE (m1:Comestible {name: 'Milkshake', flavour: 'Strawberry'})
CREATE (p2:Comestible {name: 'Hamburger'})
CREATE (m2:Comestible {name: 'Cola'})
CREATE (u1)-[:lives_in]->(b1)
CREATE (u1)-[:likes]->(p1)
CREATE (u1)-[:likes]->(m1)
CREATE (u2)-[:lives_in]->(b2)
CREATE (u2)-[:likes]->(p2)
CREATE (u2)-[:likes]->(m2)
CREATE (u3)-[:lives_in]->(b2)
CREATE (u3)-[:likes]->(p1)
CREATE (u3)-[:likes]->(m2)
RETURN true
$$) as (id ag_catalog.agtype);
SET search_path = ag_catalog, "$user", public;
```
## Query
Below is an illustrative query.
```
SELECT * FROM ag_catalog.cypher('nesteddemo', $$
MATCH (b:Building)<-[:lives_in]-(u:User)-[:likes]->(c:Comestible)
WITH {name: u.name, favouriteFoods: COLLECT(c)} AS person, u, b
RETURN b.name, COLLECT([person]) AS people
$$) as (building ag_catalog.agtype, userdata ag_catalog.agtype);
```
A couple of things to note:
- The derived object (`person`) needs to be wrapped in an array in order to be `COLLECT`ed
- The value of `favourites` in the result `userdata` is an array of arrays
Besides the slight inconvenience of having nested arrays, no real issue so far. All the data is returned.
However, when the above query is run via `pg` using the NodeJS AGE driver, `userdata`'s top level array _only contains one array_ where it should contain two. The result row for `Building Two` **should** contain `User Two` and `User Three`, but it only contains `User Three`.
This _seems_ to me like a bug, but I'm not sure if I'm doing something wrong. If so, I'm hoping one of you can point me in the right direction. This is a significant hindrance at the moment. The actual query that's producing the described result worked well in RedisGraph and (I think) Neo4J.
Please let me know your thoughts.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: dev-unsubscribe@age.apache.org.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [I] Node.js AGE driver unable to handle nested array in result set [age]
Posted by "alexgraul (via GitHub)" <gi...@apache.org>.
alexgraul commented on issue #221:
URL: https://github.com/apache/age/issues/221#issuecomment-2287531745
I think I've run into the same issue, but I can replicate with a much simpler case for replication:
To confirm this is a parsing issue I used this query to generate the test string:
```
SELECT *
FROM cypher('testing_graph', $$
CREATE (c:car { name: '4wd', wheels: ["a",["d"]] })
RETURN c
$$) as (c agtype);
```
Returns
`{"id": 1125899906842627, "label": "car", "properties": {"name": "4wd", "wheels": ["a", ["d"]]}}::vertex`
The following test case added to `drivers/nodejs/nodejs/test/Agtype.test.ts` will fail:
```
test('Nested Array Parsing', () => {
expect(AGTypeParse('{"id": 1125899906842627, "label": "car", "properties": {"name": "4wd", "wheels": [ "a", ["d"] ]}}::vertex').get('id')).toBe(1125899906842627)
expect(AGTypeParse('{"id": 1125899906842627, "label": "car", "properties": {"name": "4wd", "wheels": [ "a", ["d"] ]}}::vertex')).toStrictEqual(new Map<string, any>(Object.entries({
id: 1125899906842627,
label: 'car',
properties: new Map(Object.entries({ name: '4wd', wheels: ['a', ['d']] }))
}));
})
```
The first `expect` is there just to confirm the return Map is completely malformed rather than a minor quirk causing `StringEquals` to fail.
The object that does come back looks like this:
`Map(2) { 'name' => '4wd', 'properties' => [ 'a', [ 'd' ] ] }`
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: dev-unsubscribe@age.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [age] eyab commented on issue #221: Node.js AGE driver unable to handle nested array in result set
Posted by "eyab (via GitHub)" <gi...@apache.org>.
eyab commented on issue #221:
URL: https://github.com/apache/age/issues/221#issuecomment-1692552163
@lnoir can you please update us on this issue? Also, what is the usecase, and if you can provide more information?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: dev-unsubscribe@age.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [incubator-age] lnoir commented on issue #221: Node.js AGE driver unable to handle nested array in result set
Posted by GitBox <gi...@apache.org>.
lnoir commented on issue #221:
URL: https://github.com/apache/incubator-age/issues/221#issuecomment-1137748799
I haven't got to the bottom of this yet, I'm still hoping someone can help me out. Below is a Node.js script that will output the results described above, to maybe save time for anyone who wants to look at this. I'll report back if I get any further.
```
const { types, Pool } = require('pg');
const { setAGETypes } = require('./age-driver/dist');
class Testing {
graphName;
config;
pool;
constructor() {
this.config = {
host: 'localhost',
port: 5432,
user: 'postgres',
pass: 'mypassword',
};
this.graphName = 'nesteddemo';
}
createPool() {
return new Promise((resolve) => {
this.pool = new Pool({
user: this.config.user,
host: this.config.host,
password: this.config.pass,
port: this.config.port,
});
this.pool.on('connect', client => {
console.log('connected')
this.init(client);
resolve();
});
this.pool.connect();
});
}
async init(client) {
console.log('@graphName', this.graphName)
try {
await client.query(`
CREATE EXTENSION IF NOT EXISTS age;
LOAD 'age';
SET search_path = ag_catalog, "$user", public;
`);
await setAGETypes(client, types);
await client.query(`SELECT create_graph('${this.graphName}')`);
}
catch(err) {
console.error(err.message);
}
}
formatQuery(query, params, varsKeys) {
let q = query;
const agPlaceholder = params ? ', $1' : '';
const types = (varsKeys || []).map(vk => `${vk?.var || vk} ag_catalog.agtype`).join(', ');
const fulLStatement = `
SELECT * FROM ag_catalog.cypher('${this.graphName}', $$
${q}
$$${agPlaceholder}) as (${types || 'n ag_catalog.agtype'});
`;
return fulLStatement;
}
async query(query, params, varsKeys) {
try {
const statement = this.formatQuery(query, params, varsKeys, '$');
if (!this.pool) await this.createPool();
const res = await this.pool.query(statement, params ? [params] : null);
return {res};
}
catch(err) {
console.error(err);
return {err, res: null};
}
}
async run() {
const query = `
MATCH (b:Building)<-[:lives_in]-(u:User)-[:likes]->(c:Comestible)
WITH {name: u.name, favourites: COLLECT(c)} AS person, u, b
RETURN b.name, COLLECT([person]) AS people
`;
const {res} = await this.query(query, null, ['name','people']);
res.rows.forEach(r => {
r.people = r.people.map(p => Object.fromEntries(p))
});
console.log(JSON.stringify(res.rows, null, 2))
}
}
const testing = new Testing();
testing.run();
```
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: dev-unsubscribe@age.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [age] lnoir commented on issue #221: Node.js AGE driver unable to handle nested array in result set
Posted by "lnoir (via GitHub)" <gi...@apache.org>.
lnoir commented on issue #221:
URL: https://github.com/apache/age/issues/221#issuecomment-1722439716
@eyab I didn't get any further with this and actually went with AgensGraph instead of the AGE extension as it didn't have the same issue. The code I provided should be sufficient to determine if there is a bug or not, but I've moved on from this over a year ago so have nothing to add. If it's not worth investigating then it can be closed.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: dev-unsubscribe@age.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org