Returning values
A function can return values with the RETURN
instruction.
Defining the returned types in a function declaration
Function definitions can specify the list of data types returned by the function with the
RETURNS
clause.
Note: The
RETURNS
clause in the function header is not mandatory. However, it is
recommended, to define the complete function signature, and take advantage of better code checking
by the compiler.If the function returns a single value, specify the data type after the RETURNS
clause:
FUNCTION get_count() RETURNS INT
...
END FUNCTION
Note: When the function returns a single value/type, it is also possible to enclose the type in
parentheses:
FUNCTION get_count() RETURNS (INT)
But for convenience, the
parentheses are optional when only one return type is used.If the function returns a several values, you must specify the data types after the
RETURNS
clause inside parentheses:
FUNCTION get_address() RETURNS ( CHAR(5), VARCHAR(100), INTEGER )
...
END FUNCTION
When the function returns no values, enforce compiler verification by using the
RETURNS()
clause in the function
head:DEFINE the_list DYNAMIC ARRAY OF STRING
FUNCTION clear_list() RETURNS ()
CALL the_list.clear()
RETURN 0
| Invalid number of return values.
| See error number -8415.
END FUNCTION
The RETURNS
types specification can use base data types such as
INTEGER
, user-defined types, and classes.
SCHEMA stores
TYPE t_cust DYNAMIC ARRAY OF RECORD LIKE customer.*
...
FUNCTION get_cust_list() RETURNS t_cust
...
END FUNCTION
Returning from the function
Use the RETURN
instruction in
the body of the function, to push a list of values on the stack, and return to the caller.
The
RETURN
instruction takes an optional comma-separated list of
expressions:FUNCTION get_address() RETURNS ( CHAR(5), VARCHAR(100), INTEGER )
DEFINE zipcode CHAR(5),
street VARCHAR(100),
city INTEGER
...
RETURN zipcode, street, city
END FUNCTION
The next example shows a function returning a single
value:
FUNCTION get_count() RETURNS ()
...
RETURN count
END FUNCTION
If a function does not need to return a value, the
RETURN
instruction can be
used without
arguments:FUNCTION show_notfound() RETURNS ()
IF SQLCA.SQLCODE==0 THEN
RETURN
END IF
...
END FUNCTION
Expressions using functions returning a single value
When a function returns a single value, it can be invoked in expressions:
MAIN
DEFINE r INTEGER
LET r = 500 + add(50,5)
END MAIN
FUNCTION add(x,y) RETURNS INTEGER
DEFINE x, y INTEGER
RETURN (x + y)
END FUNCTION
Calling a function returning a list of values
Functions returning multiple values must be invoked with a
CALL
instruction
using the RETURNING
clause. Values specified in RETURN
statement
must correspond in number and position to the RETURNING
clause of the
CALL
instruction, and must be of the same or of compatible data types, to the
variables in the RETURNING
clause of the CALL
statement. An error
results if the list of returned values in the RETURN
statement conflicts in number
or in data type with the RETURNING
clause of the CALL
statement
that invokes the
function.MAIN
DEFINE zipcode CHAR(5),
street VARCHAR(100),
city VARCHAR(50)
CALL get_address() RETURNING zipcode, street, city
END MAIN
FUNCTION get_default_address() RETURNS (STRING,STRING,STRING)
RETURN "00000", "<undefined>", "<undefined>"
END FUNCTION
Returning complex structures
When returning simple built-in types like INTEGER
, values are copied on the
stack and copied to the caller variables.
When returning a
RECORD
structure,
all values are expanded on the stack (it is recommended to define a TYPE
for the record structure. It can then
be used in the RETURNS
clause):TYPE t_rec RECORD
pkey INT,
name VARCHAR(20)
END RECORD
MAIN
DEFINE r1 t_rec
CALL get_rec() RETURNING r1.*
DISPLAY r1.*
END MAIN
FUNCTION get_rec() RETURNS (t_rec)
DEFINE r t_rec
LET r.pkey = 999
LET r.name = "Mike"
RETURN r.*
END FUNCTION
When returning complex types such as objects or dynamic arrays, the reference of the element are
copied on the stack (this means that you can create an object inside a function, and return its
reference in the
RETURN
statement):MAIN
DEFINE c base.Channel
LET c = open_file("myfile.txt")
...
END MAIN
FUNCTION open_file(filename)
DEFINE filename STRING
DEFINE c base.Channel
TRY
LET c = base.Channel.create()
CALL c.openFile(filename, "r")
RETURN c
CATCH
RETURN NULL
END TRY
END FUNCTION