Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions regress/expected/cypher_call.out
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,58 @@ SELECT * FROM cypher('cypher_call', $$ CALL sqrt(64) YIELD sqrt CALL agtype_sum(
ERROR: duplicate variable "sqrt"
LINE 1: ...LL sqrt(64) YIELD sqrt CALL agtype_sum(2,2) YIELD agtype_sum...
^
-- Fix CALL/YIELD issues
CREATE OR REPLACE FUNCTION myfunc(i agtype)
RETURNS agtype
LANGUAGE plpgsql
AS $$
DECLARE
result agtype;
BEGIN
RETURN ag_catalog.age_sqrt(i);
END;
$$;
-- should have no errors
SELECT * FROM cypher('cypher_call', $$ CALL ag_catalog.age_sqrt(64) YIELD age_sqrt RETURN age_sqrt $$) as (sqrt agtype);
sqrt
------
8.0
(1 row)

SELECT * FROM cypher('cypher_call', $$ CALL myfunc(25) YIELD myfunc RETURN myfunc $$) as (result agtype);
result
--------
5.0
(1 row)

SELECT * FROM cypher('cypher_call', $$ CALL ag_catalog.myfunc(25) YIELD myfunc RETURN myfunc $$) as (result agtype);
result
--------
5.0
(1 row)

-- should error
SELECT * FROM cypher('cypher_call', $$ CALL myfunc() YIELD myfunc RETURN myfunc $$) as (result agtype);
ERROR: function myfunc does not exist
LINE 1: SELECT * FROM cypher('cypher_call', $$ CALL myfunc() YIELD m...
^
HINT: If the function is from an external extension, make sure the extension is installed and the function is in the search path.
SELECT * FROM cypher('cypher_call', $$ CALL myfunz(25) YIELD myfunc RETURN myfunc $$) as (result agtype);
ERROR: function myfunz does not exist
LINE 1: SELECT * FROM cypher('cypher_call', $$ CALL myfunz(25) YIELD...
^
HINT: If the function is from an external extension, make sure the extension is installed and the function is in the search path.
SELECT * FROM cypher('cypher_call', $$ CALL ag_catalog.myfunc() YIELD myfunc RETURN myfunc $$) as (result agtype);
ERROR: function ag_catalog.myfunc() does not exist
LINE 1: ...T * FROM cypher('cypher_call', $$ CALL ag_catalog.myfunc() Y...
^
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
SELECT * FROM cypher('cypher_call', $$ CALL ag_catalog.myfunz(25) YIELD myfunc RETURN myfunc $$) as (result agtype);
ERROR: function ag_catalog.myfunz(agtype) does not exist
LINE 1: ...OM cypher('cypher_call', $$ CALL ag_catalog.myfunz(25) YIELD...
^
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
DROP FUNCTION myfunc;
DROP SCHEMA call_stmt_test CASCADE;
NOTICE: drop cascades to function call_stmt_test.add_agtype(agtype,agtype)
SELECT drop_graph('cypher_call', true);
Expand Down
25 changes: 25 additions & 0 deletions regress/sql/cypher_call.sql
Original file line number Diff line number Diff line change
Expand Up @@ -104,5 +104,30 @@ SELECT * FROM cypher('cypher_call', $$ CALL sqrt(64) YIELD sqrt AS sqrt1 CALL sq
SELECT * FROM cypher('cypher_call', $$ CALL sqrt(64) YIELD sqrt AS sqrt1 CALL sqrt(81) YIELD sqrt AS sqrt1 RETURN sqrt1, sqrt1 $$) as (a agtype, b agtype);
SELECT * FROM cypher('cypher_call', $$ CALL sqrt(64) YIELD sqrt CALL agtype_sum(2,2) YIELD agtype_sum AS sqrt RETURN sqrt, sqrt $$) as (a agtype, b agtype);

-- Fix CALL/YIELD issues
CREATE OR REPLACE FUNCTION myfunc(i agtype)
RETURNS agtype
LANGUAGE plpgsql
AS $$
DECLARE
result agtype;
BEGIN
RETURN ag_catalog.age_sqrt(i);
END;
$$;

-- should have no errors
SELECT * FROM cypher('cypher_call', $$ CALL ag_catalog.age_sqrt(64) YIELD age_sqrt RETURN age_sqrt $$) as (sqrt agtype);
SELECT * FROM cypher('cypher_call', $$ CALL myfunc(25) YIELD myfunc RETURN myfunc $$) as (result agtype);
SELECT * FROM cypher('cypher_call', $$ CALL ag_catalog.myfunc(25) YIELD myfunc RETURN myfunc $$) as (result agtype);

-- should error
SELECT * FROM cypher('cypher_call', $$ CALL myfunc() YIELD myfunc RETURN myfunc $$) as (result agtype);
SELECT * FROM cypher('cypher_call', $$ CALL myfunz(25) YIELD myfunc RETURN myfunc $$) as (result agtype);
SELECT * FROM cypher('cypher_call', $$ CALL ag_catalog.myfunc() YIELD myfunc RETURN myfunc $$) as (result agtype);
SELECT * FROM cypher('cypher_call', $$ CALL ag_catalog.myfunz(25) YIELD myfunc RETURN myfunc $$) as (result agtype);

DROP FUNCTION myfunc;

DROP SCHEMA call_stmt_test CASCADE;
SELECT drop_graph('cypher_call', true);
6 changes: 3 additions & 3 deletions src/backend/parser/cypher_clause.c
Original file line number Diff line number Diff line change
Expand Up @@ -1153,7 +1153,7 @@ static Query *transform_cypher_call_subquery(cypher_parsestate *cpstate,
EXPR_KIND_FROM_FUNCTION));

/* retrieve the column name from funccall */
colName = strVal(linitial(self->funccall->funcname));
colName = strVal(llast(self->funccall->funcname));

/* make a targetentry from the funcexpr node */
tle = makeTargetEntry((Expr *) node,
Expand Down Expand Up @@ -3957,7 +3957,7 @@ static List *transform_map_to_ind_recursive(cypher_parsestate *cpstate,
*
* Transforms the map to a list of equality irrespective of
* value type. For example,
*
*
* x.name = 'xyz'
* x.map = {"city": "abc", "street": {"name": "pqr", "number": 123}}
* x.list = [9, 8, 7]
Expand Down Expand Up @@ -4011,7 +4011,7 @@ static List *transform_map_to_ind_top_level(cypher_parsestate *cpstate,
qual = (Node *)make_op(pstate, op, lhs, rhs, last_srf, -1);
quals = lappend(quals, qual);
}

return quals;
}

Expand Down
13 changes: 6 additions & 7 deletions src/backend/parser/cypher_expr.c
Original file line number Diff line number Diff line change
Expand Up @@ -2036,7 +2036,7 @@ static Node *transform_FuncCall(cypher_parsestate *cpstate, FuncCall *fn)
targs = lcons(c, targs);
}
}
/*
/*
* If it's not in age, check if it's a potential call to some function
* in another installed extension.
*/
Expand All @@ -2055,14 +2055,13 @@ static Node *transform_FuncCall(cypher_parsestate *cpstate, FuncCall *fn)
procform, extension);
return retval;
}
/*
* Else we have a function that is in the search_path, and not
* qualified, but is not in an extension. Pass it through.
*/
else
{
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_FUNCTION),
errmsg("function %s does not exist", name),
errhint("If the function is from an external extension, "
"make sure the extension is installed and the "
"function is in the search path.")));
fname = fn->funcname;
}
}
/* no function found */
Expand Down