-
Notifications
You must be signed in to change notification settings - Fork 413
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
VLE still has a bug when I try to run PL/pgSQL functions with VLE statements inside #220
Comments
Hi, you need to isolate the vle |
@JoshInnis But I only use Match ()-[*]-() for query in the |
@jihot2000 |
There is a fundamental difference between |
@JoshInnis I didn't get your point. It is |
|
I think the list structure changed through the script as follows: after create list:
after prepend node 'a':
after prepend node 'b':
so the cypher statements inside
should return both 'b' and 'a'. Do I have some troubles with the analysis above? |
Or perhaps I should ask what |
I think the |
??? Graphid AT THIS POINT is guaranteed to be unique on a schema per schema level. We have lost each other, I need more details to assist :). A graph === a schema AT THIS POINT. The |
Please review my first post after the apology for missing your point. I do believe there is a subtle difference between expected and results, where you are wrong and need to review. |
@JoshInnis Thank you for your patience. Perhaps I have some mistakes. I said "I think the id in the graph is global" meas the id of a vertext inside a graph is globally unique (Maybe this is wrong). For example, the You said specify |
@jihot2000 I will not do your job for you. The specifics should help you... |
Thank you. I've read all the docs of AGE. Perhaps I missed something important. I simplified my sql code into a test case as a sql file above. It is about create/add/show operations of a link list. I don't know how to make it more simple. |
I split the sql file into two files. First, the CREATE SCHEMA test_vle;
SET search_path = test_vle, ag_catalog, "$user";
SELECT create_graph('mygraph');
SELECT create_vlabel('mygraph', 'head');
SELECT create_vlabel('mygraph', 'tail');
SELECT create_vlabel('mygraph', 'node');
SELECT create_elabel('mygraph', 'next');
CREATE OR REPLACE FUNCTION create_list(list_name text)
RETURNS void
LANGUAGE 'plpgsql'
AS $$
DECLARE
ag_param agtype;
BEGIN
ag_param = FORMAT('{"list_name": "%s"}', $1)::agtype;
PERFORM * FROM cypher('mygraph', $CYPHER$
MERGE (:head {name: $list_name})-[:next]->(:tail {name: $list_name})
$CYPHER$, ag_param) AS (a agtype);
END $$;
CREATE OR REPLACE FUNCTION prepend_node(list_name text, node_content text)
RETURNS void
LANGUAGE 'plpgsql'
AS $$
DECLARE
ag_param agtype;
BEGIN
ag_param = FORMAT('{"list_name": "%s", "node_content": "%s"}', $1, $2)::agtype;
PERFORM * FROM cypher('mygraph', $CYPHER$
MATCH (h:head {name: $list_name})-[e:next]->(v)
DELETE e
CREATE (h)-[:next]->(:node {content: $node_content})-[:next]->(v)
$CYPHER$, ag_param) AS (a agtype);
END $$;
CREATE OR REPLACE FUNCTION show_list_use_loop(list_name text)
RETURNS TABLE(node agtype)
LANGUAGE 'plpgsql'
AS $$
DECLARE
node_id bigint;
ag_param agtype;
BEGIN
ag_param = FORMAT('{"list_name": "%s"}', $1)::agtype;
SELECT g.id INTO node_id FROM cypher('mygraph', $CYPHER$
MATCH (h:head {name: $list_name})
RETURN id(h)
$CYPHER$, ag_param) AS g(id bigint);
IF node_id IS NULL THEN
RETURN;
END IF;
LOOP
ag_param = FORMAT('{"node_id": %s}', node_id)::agtype;
SELECT g.id, g.node INTO node_id, node FROM cypher('mygraph', $CYPHER$
MATCH (p)-[e:next]->(v:node)
WHERE id(p) = $node_id
RETURN id(v), v
$CYPHER$, ag_param) AS g(id bigint, node agtype);
EXIT WHEN node_id IS NULL;
RETURN NEXT;
END LOOP;
END $$;
-- create a list
SELECT create_list('list01');
-- prepend a node 'a'
SELECT prepend_node('list01', 'a');
SELECT * FROM show_list_use_loop('list01');
-- prepend a node 'b'
SELECT prepend_node('list01', 'b');
SELECT * FROM show_list_use_loop('list01');
SELECT drop_graph('mygraph', true); Its output is right:
Second, the 'use_vle.sql': CREATE SCHEMA test_vle;
SET search_path = test_vle, ag_catalog, "$user";
SELECT create_graph('mygraph');
SELECT create_vlabel('mygraph', 'head');
SELECT create_vlabel('mygraph', 'tail');
SELECT create_vlabel('mygraph', 'node');
SELECT create_elabel('mygraph', 'next');
CREATE OR REPLACE FUNCTION create_list(list_name text)
RETURNS void
LANGUAGE 'plpgsql'
AS $$
DECLARE
ag_param agtype;
BEGIN
ag_param = FORMAT('{"list_name": "%s"}', $1)::agtype;
PERFORM * FROM cypher('mygraph', $CYPHER$
MERGE (:head {name: $list_name})-[:next]->(:tail {name: $list_name})
$CYPHER$, ag_param) AS (a agtype);
END $$;
CREATE OR REPLACE FUNCTION prepend_node(list_name text, node_content text)
RETURNS void
LANGUAGE 'plpgsql'
AS $$
DECLARE
ag_param agtype;
BEGIN
ag_param = FORMAT('{"list_name": "%s", "node_content": "%s"}', $1, $2)::agtype;
PERFORM * FROM cypher('mygraph', $CYPHER$
MATCH (h:head {name: $list_name})-[e:next]->(v)
DELETE e
CREATE (h)-[:next]->(:node {content: $node_content})-[:next]->(v)
$CYPHER$, ag_param) AS (a agtype);
END $$;
CREATE OR REPLACE FUNCTION show_list_use_vle(list_name text)
RETURNS TABLE(node agtype)
LANGUAGE 'plpgsql'
AS $$
DECLARE
ag_param agtype;
BEGIN
ag_param = FORMAT('{"list_name": "%s"}', $1)::agtype;
RETURN QUERY
SELECT * FROM cypher('mygraph', $CYPHER$
MATCH (h:head {name: $list_name})-[e:next*]->(v:node)
RETURN v
$CYPHER$, ag_param) AS (node agtype);
END $$;
-- create a list
SELECT create_list('list01');
-- prepend a node 'a'
SELECT prepend_node('list01', 'a');
SELECT * FROM show_list_use_vle('list01');
-- prepend a node 'b'
SELECT prepend_node('list01', 'b');
SELECT * FROM show_list_use_vle('list01');
SELECT drop_graph('mygraph', true);
DROP SCHEMA test_vle CASCADE; Its output is wrong:
The question is the output after prepend node 'b' of Here is all the information about the question. I hope I am not asking a stupid question :-P |
I rewrite my question in issue #222 to make it more clear |
@JoshInnis Thank you. I reviewd the docs of AGE. In /intro/types.md, I find
So, I made an assumption that the ids of vertices in different labels will not be the same. And I can query a vertex with its id only. If I went wrong with the doc, please let me know. I rewrite my question in issue #222 . I removed all the functions except English is not my native language. If some of my words look offensive, I didn't mean to that. Forgive me. |
I have reproduced and found what the issue is with this particular bug. It is not related to the other VLE bug, other than also being an issue with transaction ids. So, if you are happy with that issue being resolved, please close that ticket. The issue here has to do with the way the VLE caches contexts, which are expensive to recreate. The VLE stores the grammar node ID as an index into a cache (that holds these contexts) for later retrieval for chained non-updating commands with a VLE component. Grammar node IDs change from position to position, line to line. In other words, they are unique to that particular VLE command. The problem here is that the grammar node does not change as it is in a procedure. So, the VLE caching mechanism sees it as repeating a previous command. When writing the caching mechanism, I must have overlooked the possibility of the a VLE component inside a procedure where the grammar node ID would be static. I need to think about how this can be resolved and what the implications would be. |
@jrgemignani If it is not a severe bug to be solved, feel free to close this issue. |
I have created a patch, that is currently in review, that should address this particular issue. It should be ready by the end of the week. |
This fix allows locally cached contexts to be rebuilt for actions that update the specified underlying graph. Local contexts are tied to their VLE grammar node IDs, which is unique to each command. This ID allows the caching of contexts, which allows their reuse, thus saving the expensive costs of rebuilding a new local context every time, for the same command. Its expected use was within a single command line. This is because the VLE SRF may get invoked many times through the single grammar node's lifetime on that line. However, it was overlooked in static procedures (stored procedures and user created functions) that these grammar nodes might persist longer than the expected life of just one command line. This fix allows them to persist and update along with the graph. Added regression tests.
The patch is in and should resolve this issue. Please make sure to close any open tickets related to this issue if it is resolved. |
@jrgemignani |
Describe the bug
VLE still has a bug when I try to run my PL/pgSQL functions with VLE statements inside.
How are you accessing AGE (Command line, driver, etc.)?
run a sql file using psql command line
the sql file
Expected behavior
The bug show_list_use_vle line only shows node 'a':
The show_list_use_loop line shows the expected result:
Environment (please complete the following information):
PostgreSQL 11 and AGE commit id 95ca659
The text was updated successfully, but these errors were encountered: