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 INTEGER
...
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 (INTEGER)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 FUNCTIONThe 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 FUNCTIONThe next example shows a function returning a single
value:
FUNCTION get_count() RETURNS INTEGER
...
RETURN count
END FUNCTIONIf 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 FUNCTIONExpressions 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 FUNCTIONCalling 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 FUNCTIONReturning 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 INTEGER,
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 FUNCTIONWhen 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