JoSQL supports a number of built-in functions (although these are actually provided by classes defined in the
org.josql.functions
package). It was decided early on to provide a mechanism for functions rather than trying to support the execution of arbitrary Java methods, the main reasons for this is the complexities involved in trying access the correct class, trying to perform package resolution and finding the correct method to execute, not to mention syntax issues.
Instead a framework of function handling is provided such that the following can be performed:
SELECT avg (:_allobjs, length)
FROM java.io.File
In this case the
avg
function will take in a List (of all objects currently in the scope, see
Query Execution for more details about execution scope) and determine the average length of the files.
JoSQL allows ANY method to be used for as a function. The developer then passes object instances to JoSQL which will find the method and execute it at the appropriate time.
A function is defined by the name of the method (please note that function names are case-sensitive) and then braces with a comma-separated list of arguments. Any of the normal SQL expressions, bind variables etc can be used as arguments to the function.
If all the arguments to a function have
fixed results then the function will only be executed once. The return value will be remembered and that value returned whenever the function expression is evaluated again. This behavior occurs for
built in functions and
custom functions.
If you have a function that should return different values for the same input then use a dummy
bind variable, or pass an
accessor as an argument to ensure that the function won't be considered to have a fixed result.
As of version
1.9 you can also have your function handler implement the marker interface
NotFixedResults, this will tell JoSQL that none of the functions in the handler return a fixed result. In other words, regardless of the input values the function will be evaluated as many times as is required. Note this applies to ALL the functions in the handler, you should still use dummy bind variables if you want to limit the behavior to single functions.
SELECT *
FROM java.lang.Object
WHERE myFunction ('hello world')
SELECT *
FROM java.lang.Object
WHERE myFunction ('hello world', :_currobj)
No argument functions
An exception to this rule is functions that have no arguments. In this case the function is considered to never have a fixed result (since there is no input) and so it will be called every time.
SELECT *
FROM java.lang.Object
WHERE hashCode = random ()