
r.tck.1.0.0-M06.source-code.ProcedureCallAcceptance.feature Maven / Gradle / Ivy
#
# Copyright (c) 2002-2016 "Neo Technology,"
# Network Engine for Objects in Lund AB [http://neotechnology.com]
#
# This file is part of Neo4j.
#
# Neo4j is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
#
Feature: ProcedureCallAcceptance
Background:
Given an empty graph
Scenario: In-query call to procedure that takes arguments fails when trying to pass them implicitly
And there exists a procedure test.my.proc(in :: INTEGER?) :: (out :: INTEGER?):
| in | out |
When executing query:
"""
CALL test.my.proc YIELD out
RETURN out
"""
Then a SyntaxError should be raised at compile time: InvalidArgumentPassingMode
Scenario: Standalone call to procedure that takes no arguments
And there exists a procedure test.labels() :: (label :: STRING?):
| label |
| 'A' |
| 'B' |
| 'C' |
When executing query:
"""
CALL test.labels()
"""
Then the result should be, in order:
| label |
| 'A' |
| 'B' |
| 'C' |
And no side effects
Scenario: In-query call to procedure that takes no arguments
And there exists a procedure test.labels() :: (label :: STRING?):
| label |
| 'A' |
| 'B' |
| 'C' |
When executing query:
"""
CALL test.labels() YIELD label
RETURN label
"""
Then the result should be, in order:
| label |
| 'A' |
| 'B' |
| 'C' |
And no side effects
Scenario: Calling the same procedure twice using the same outputs in each call
And there exists a procedure test.labels() :: (label :: STRING?):
| label |
| 'A' |
| 'B' |
| 'C' |
When executing query:
"""
CALL test.labels() YIELD label
WITH count(*) AS c
CALL test.labels() YIELD label
RETURN *
"""
Then the result should be, in order:
| label | c |
| 'A' | 3 |
| 'B' | 3 |
| 'C' | 3 |
And no side effects
Scenario: Standalone call to VOID procedure that takes no arguments
And there exists a procedure test.doNothing() :: VOID:
|
When executing query:
"""
CALL test.doNothing()
"""
Then the result should be empty
And no side effects
Scenario: In-query call to VOID procedure that takes no arguments
And there exists a procedure test.doNothing() :: VOID:
|
When executing query:
"""
MATCH (n)
CALL test.doNothing()
RETURN n
"""
Then the result should be empty
And no side effects
Scenario: In-query call to VOID procedure does not consume rows
And there exists a procedure test.doNothing() :: VOID:
|
And having executed:
"""
CREATE (:A {name: 'a'})
CREATE (:B {name: 'b'})
CREATE (:C {name: 'c'})
"""
When executing query:
"""
MATCH (n)
CALL test.doNothing()
RETURN n.name AS `name`
"""
Then the result should be:
| name |
| 'a' |
| 'b' |
| 'c' |
And no side effects
Scenario: Standalone call to VOID procedure that takes no arguments, called with implicit arguments
And there exists a procedure test.doNothing() :: VOID:
|
When executing query:
"""
CALL test.doNothing
"""
Then the result should be empty
And no side effects
Scenario: In-query call to procedure that takes no arguments and yields no results
And there exists a procedure test.doNothing() :: ():
|
When executing query:
"""
CALL test.doNothing() YIELD - RETURN 1
"""
Then the result should be empty
And no side effects
Scenario: Standalone call to procedure that takes no arguments and yields no results
And there exists a procedure test.doNothing() :: ():
|
When executing query:
"""
CALL test.doNothing()
"""
Then the result should be empty
And no side effects
Scenario: Standalone call to procedure that takes no arguments and yields no results, called with implicit arguments
And there exists a procedure test.doNothing() :: ():
|
When executing query:
"""
CALL test.doNothing
"""
Then the result should be empty
And no side effects
Scenario: In-query call to procedure with explicit arguments
And there exists a procedure test.my.proc(name :: STRING?, id :: INTEGER?) :: (city :: STRING?, country_code :: INTEGER?):
| name | id | city | country_code |
| 'Andres' | 1 | 'Malmö' | 46 |
| 'Tobias' | 1 | 'Malmö' | 46 |
| 'Mats' | 1 | 'Malmö' | 46 |
| 'Stefan' | 1 | 'Berlin' | 49 |
| 'Stefan' | 2 | 'München' | 49 |
| 'Petra' | 1 | 'London' | 44 |
When executing query:
"""
CALL test.my.proc('Stefan', 1) YIELD city, country_code
RETURN city, country_code
"""
Then the result should be, in order:
| city | country_code |
| 'Berlin' | 49 |
Scenario: In-query call to procedure with explicit arguments that drops all result fields
And there exists a procedure test.my.proc(name :: STRING?, id :: INTEGER?) :: (city :: STRING?, country_code :: INTEGER?):
| name | id | city | country_code |
| 'Andres' | 1 | 'Malmö' | 46 |
| 'Tobias' | 1 | 'Malmö' | 46 |
| 'Mats' | 1 | 'Malmö' | 46 |
| 'Stefan' | 1 | 'Berlin' | 49 |
| 'Stefan' | 2 | 'München' | 49 |
| 'Petra' | 1 | 'London' | 44 |
When executing query:
"""
WITH 'Stefan' AS name, 1 AS id
CALL test.my.proc(name, id) YIELD -
RETURN name, id, count(*) AS count
"""
Then the result should be, in order:
| name | id | count |
| 'Stefan' | 1 | 1 |
Scenario: Standalone call to procedure with explicit arguments
And there exists a procedure test.my.proc(name :: STRING?, id :: INTEGER?) :: (city :: STRING?, country_code :: INTEGER?):
| name | id | city | country_code |
| 'Andres' | 1 | 'Malmö' | 46 |
| 'Tobias' | 1 | 'Malmö' | 46 |
| 'Mats' | 1 | 'Malmö' | 46 |
| 'Stefan' | 1 | 'Berlin' | 49 |
| 'Stefan' | 2 | 'München' | 49 |
| 'Petra' | 1 | 'London' | 44 |
When executing query:
"""
CALL test.my.proc('Stefan', 1)
"""
Then the result should be, in order:
| city | country_code |
| 'Berlin' | 49 |
Scenario: Standalone call to procedure with implicit arguments
And there exists a procedure test.my.proc(name :: STRING?, id :: INTEGER?) :: (city :: STRING?, country_code :: INTEGER?):
| name | id | city | country_code |
| 'Andres' | 1 | 'Malmö' | 46 |
| 'Tobias' | 1 | 'Malmö' | 46 |
| 'Mats' | 1 | 'Malmö' | 46 |
| 'Stefan' | 1 | 'Berlin' | 49 |
| 'Stefan' | 2 | 'München' | 49 |
| 'Petra' | 1 | 'London' | 44 |
And parameters are:
| name | 'Stefan' |
| id | 1 |
When executing query:
"""
CALL test.my.proc
"""
Then the result should be, in order:
| city | country_code |
| 'Berlin' | 49 |
And no side effects
Scenario: Standalone call to procedure with argument of type NUMBER accepts value of type INTEGER
And there exists a procedure test.my.proc(in :: NUMBER?) :: (out :: STRING?):
| in | out |
| 42 | 'wisdom' |
| 42.3 | 'about right' |
When executing query:
"""
CALL test.my.proc(42)
"""
Then the result should be, in order:
| out |
| 'wisdom' |
And no side effects
Scenario: In-query call to procedure with argument of type NUMBER accepts value of type INTEGER
And there exists a procedure test.my.proc(in :: NUMBER?) :: (out :: STRING?):
| in | out |
| 42 | 'wisdom' |
| 42.3 | 'about right' |
When executing query:
"""
CALL test.my.proc(42) YIELD out
RETURN out
"""
Then the result should be, in order:
| out |
| 'wisdom' |
And no side effects
Scenario: Standalone call to procedure with argument of type NUMBER accepts value of type FLOAT
And there exists a procedure test.my.proc(in :: NUMBER?) :: (out :: STRING?):
| in | out |
| 42 | 'wisdom' |
| 42.3 | 'about right' |
When executing query:
"""
CALL test.my.proc(42.3)
"""
Then the result should be, in order:
| out |
| 'about right' |
And no side effects
Scenario: In-query call to procedure with argument of type NUMBER accepts value of type FLOAT
And there exists a procedure test.my.proc(in :: NUMBER?) :: (out :: STRING?):
| in | out |
| 42 | 'wisdom' |
| 42.3 | 'about right' |
When executing query:
"""
CALL test.my.proc(42.3) YIELD out
RETURN out
"""
Then the result should be, in order:
| out |
| 'about right' |
And no side effects
Scenario: Standalone call to procedure with argument of type FLOAT accepts value of type INTEGER
And there exists a procedure test.my.proc(in :: FLOAT?) :: (out :: STRING?):
| in | out |
| 42.0 | 'close enough' |
When executing query:
"""
CALL test.my.proc(42)
"""
Then the result should be, in order:
| out |
| 'close enough' |
And no side effects
Scenario: In-query call to procedure with argument of type FLOAT accepts value of type INTEGER
And there exists a procedure test.my.proc(in :: FLOAT?) :: (out :: STRING?):
| in | out |
| 42.0 | 'close enough' |
When executing query:
"""
CALL test.my.proc(42) YIELD out
RETURN out
"""
Then the result should be, in order:
| out |
| 'close enough' |
And no side effects
Scenario: Standalone call to procedure with argument of type INTEGER accepts value of type FLOAT
And there exists a procedure test.my.proc(in :: INTEGER?) :: (out :: STRING?):
| in | out |
| 42 | 'close enough' |
When executing query:
"""
CALL test.my.proc(42.0)
"""
Then the result should be, in order:
| out |
| 'close enough' |
And no side effects
Scenario: In-query call to procedure with argument of type INTEGER accepts value of type FLOAT
And there exists a procedure test.my.proc(in :: INTEGER?) :: (out :: STRING?):
| in | out |
| 42 | 'close enough' |
When executing query:
"""
CALL test.my.proc(42.0) YIELD out
RETURN out
"""
Then the result should be, in order:
| out |
| 'close enough' |
And no side effects
Scenario: Standalone call to procedure with null argument
And there exists a procedure test.my.proc(in :: INTEGER?) :: (out :: STRING?):
| in | out |
| null | 'nix' |
When executing query:
"""
CALL test.my.proc(null)
"""
Then the result should be, in order:
| out |
| 'nix' |
And no side effects
Scenario: In-query call to procedure with null argument
And there exists a procedure test.my.proc(in :: INTEGER?) :: (out :: STRING?):
| in | out |
| null | 'nix' |
When executing query:
"""
CALL test.my.proc(null) YIELD out
RETURN out
"""
Then the result should be, in order:
| out |
| 'nix' |
And no side effects
Scenario: Standalone call to procedure should fail if input type is wrong
And there exists a procedure test.my.proc(in :: INTEGER?) :: (out :: INTEGER?):
| in | out |
When executing query:
"""
CALL test.my.proc(true)
"""
Then a SyntaxError should be raised at compile time: InvalidArgumentType
Scenario: In-query call to procedure should fail if input type is wrong
And there exists a procedure test.my.proc(in :: INTEGER?) :: (out :: INTEGER?):
| in | out |
When executing query:
"""
CALL test.my.proc(true) YIELD out
RETURN out
"""
Then a SyntaxError should be raised at compile time: InvalidArgumentType
Scenario: Standalone call to procedure should fail if explicit argument is missing
And there exists a procedure test.my.proc(name :: STRING?, in :: INTEGER?) :: (out :: INTEGER?):
| name | in | out |
When executing query:
"""
CALL test.my.proc('Dobby')
"""
Then a SyntaxError should be raised at compile time: InvalidNumberOfArguments
Scenario: In-query call to procedure should fail if explicit argument is missing
And there exists a procedure test.my.proc(name :: STRING?, in :: INTEGER?) :: (out :: INTEGER?):
| name | in | out |
When executing query:
"""
CALL test.my.proc('Dobby') YIELD out
RETURN out
"""
Then a SyntaxError should be raised at compile time: InvalidNumberOfArguments
Scenario: Standalone call to procedure should fail if too many explicit argument are given
And there exists a procedure test.my.proc(in :: INTEGER?) :: (out :: INTEGER?):
| in | out |
When executing query:
"""
CALL test.my.proc(1, 2, 3, 4)
"""
Then a SyntaxError should be raised at compile time: InvalidNumberOfArguments
Scenario: In-query call to procedure should fail if too many explicit argument are given
And there exists a procedure test.my.proc(in :: INTEGER?) :: (out :: INTEGER?):
| in | out |
When executing query:
"""
CALL test.my.proc(1, 2, 3, 4) YIELD out
RETURN out
"""
Then a SyntaxError should be raised at compile time: InvalidNumberOfArguments
Scenario: Standalone call to procedure should fail if implicit argument is missing
And there exists a procedure test.my.proc(name :: STRING?, in :: INTEGER?) :: (out :: INTEGER?):
| name | in | out |
And parameters are:
| name | 'Stefan' |
When executing query:
"""
CALL test.my.proc
"""
Then a ParameterMissing should be raised at compile time: MissingParameter
Scenario: In-query call to procedure that has outputs fails if no outputs are yielded
And there exists a procedure test.my.proc(in :: INTEGER?) :: (out :: INTEGER?):
| in | out |
When executing query:
"""
CALL test.my.proc(1)
RETURN out
"""
Then a SyntaxError should be raised at compile time: UndefinedVariable
Scenario: In-query call to procedure that both takes arguments and has outputs fails if the arguments are passed implicitly and no outputs are yielded
And there exists a procedure test.my.proc(in :: INTEGER?) :: (out :: INTEGER?):
| in | out |
When executing query:
"""
CALL test.my.proc
RETURN out
"""
Then a SyntaxError should be raised at compile time: UndefinedVariable
Scenario: Standalone call to unknown procedure should fail
When executing query:
"""
CALL test.my.proc
"""
Then a ProcedureError should be raised at compile time: ProcedureNotFound
Scenario: In-query call to unknown procedure should fail
When executing query:
"""
CALL test.my.proc() YIELD out
RETURN out
"""
Then a ProcedureError should be raised at compile time: ProcedureNotFound
Scenario: In-query procedure call should fail if shadowing an already bound variable
And there exists a procedure test.labels() :: (label :: STRING?):
| label |
| 'A' |
| 'B' |
| 'C' |
When executing query:
"""
WITH 'Hi' AS label
CALL test.labels() YIELD label
RETURN *
"""
Then a SyntaxError should be raised at compile time: VariableAlreadyBound
Scenario: In-query procedure call should fail if one of the argument expressions uses an aggregation function
And there exists a procedure test.labels(in :: INTEGER?) :: (label :: STRING?):
| in | label |
When executing query:
"""
MATCH (n)
CALL test.labels(count(n)) YIELD label
RETURN label
"""
Then a SyntaxError should be raised at compile time: InvalidAggregation
© 2015 - 2025 Weber Informatics LLC | Privacy Policy