Details

Improvement

Status: Closed

Minor

Resolution: Done

6.5.0

Any
Description
Functions in N1QL currently don't allow local variables (nor do they support a return statement) for example implementing a Haversin function (for the distance in Km between two lon/lat pairs has to be implemented as an inline as follows:
CREATE FUNCTION getDistanceFromLatLonInKm(lon1, lat1, lon2, lat2) {

6371 * 2 * atan2(sqrt( 
(

sin(((lat2lat1) * (3.14159265359/180))/2) * 
sin(((lat2lat1) * (3.14159265359/180))/2) + 
cos((3.14159265359/180)*(lat1)) * cos((3.14159265359/180)*(lat2)) * 
sin(((lon2lon1) * (3.14159265359/180))/2) * 
sin(((lon2lon1) * (3.14159265359/180))/2) 
)


), sqrt(1 
(

sin(((lat2lat1) * (3.14159265359/180))/2) * 
sin(((lat2lat1) * (3.14159265359/180))/2) + 
cos((3.14159265359/180)*(lat1)) * cos((3.14159265359/180)*(lat2)) * 
sin(((lon2lon1) * (3.14159265359/180))/2) * 
sin(((lon2lon1) * (3.14159265359/180))/2) 
)

))

};

Where the actual function I modeled it from would be much more readable and faster (due to eliminating repetitive calculations) using local variables and a return statement if such syntax were supported in a N1QL Javascript function
CREATE FUNCTION function getDistanceFromLatLonInKm(lon1, lat1, lon2, lat2) {

var PI = 3.14159265359 
var deg2rad = PI/180; 
var R = 6371; // Radius of the earth in km 
var dLat = deg2rad*(lat2lat1);

var dLon = deg2rad*(lon2lon1);

var a =

sin(dLat/2) * sin(dLat/2) + 
cos(deg2rad*(lat1)) * cos(deg2rad*(lat2)) *

sin(dLon/2) * sin(dLon/2) 
;

var c = 2 * atan2(sqrt(a), sqrt(1a)); 
var d = R * c; // Distance in km 
return d; 
};

Oddly Eventing allows the user to use local variables as such it seems somewhat inconsistent between the two domains
Correct. Right now, INLINE function is a N1QL expression/statement.
The workaround for this is to write a JavaScript function, which has way more flexibility