We are trying to implement addition of interval values in Snowflake.Since there is no interval data type supported in Snowflake we are trying to implement the same using an UDF. We are converting the intervals into seconds and after getting the total seconds we are converting the total second into the required target interval type.
We have implemented the same logic using SQL UDF's as well as Javascript UDF.
Javascript UDF
create or replace function js_interval(interval_1 string, interval_sign_1 double, interval_2 string, interval_sign_2 double)
returns string
language javascript
strict
as '
if ((INTERVAL_1.substring(0,1)=="-"))
{
var res = INTERVAL_1.split(":");
var res2=(res[1]*-60+res[0]*3600);
var res3= -1*res[2];
}
else
{
var res = INTERVAL_1.split(":");
var res2=(res[1]*60+res[0]*3600);
var res3= res[2];
}
if ((INTERVAL_2.substring(0,1)=="-"))
{
var res11 = INTERVAL_2.split(":");
var res22=(res11[1]*-60+res11[0]*3600);
var res33= -1*res11[2];
}
else
{
var res11 = INTERVAL_2.split(":");
var res22=(res11[1]*60+res11[0]*3600);
var res33= res11[2];
}
if(INTERVAL_SIGN_1 > 0)
{
var result1= res2*1+res3*1;
}
else
{
var result1=(res2*1+res3*1)*-1;
}
if(INTERVAL_SIGN_2 > 0)
{
var result2= res22*1+res33*1;
}
else
{
var result2=(res22*1+res33*1)*-1;
}
var final_sec= result1+result2;
if (final_sec < 0 )
{
return "-"+String(Math.trunc(Math.abs(final_sec)/3600))+":"+String(Math.trunc(Math.abs(final_sec)/60)%60)+":"+String(Math.abs(final_sec)%60);
}
else
{
return String(Math.trunc(Math.abs(final_sec)/3600))+":"+String(Math.trunc(Math.abs(final_sec)/60)%60)+":"+String(Math.abs(final_sec)%60);
}
';
SQL UDF
create or replace function addIntervalsH2S ( interval_1 varchar, interval_type_1 varchar , interval_sign_1 int, interval_2 varchar, interval_type_2 varchar, interval_sign_2 int )
returns varchar
as
'select trunc((((split_part(interval_1,\':\',1)*3600+split_part(interval_1,\':\',2)*60+split_part(interval_1,\':\',3))*interval_sign_1)+((split_part(interval_2,\':\',1)*3600+split_part(interval_2,\':\',2)*60+split_part(interval_2,\':\',3))*interval_sign_2))/3600)||\':\'||mod(trunc((((split_part(interval_1,\':\',1)*3600+split_part(interval_1,\':\',2)*60+split_part(interval_1,\':\',3))*interval_sign_1)+((split_part(interval_2,\':\',1)*3600+split_part(interval_2,\':\',2)*60+split_part(interval_2,\':\',3))*interval_sign_2))/60),60)||\':\'||mod((((split_part(interval_1,\':\',1)*3600+split_part(interval_1,\':\',2)*60+split_part(interval_1,\':\',3))*interval_sign_1)+((split_part(interval_2,\':\',1)*3600+split_part(interval_2,\':\',2)*60+split_part(interval_2,\':\',3))*interval_sign_2)),60)
end';
The performance of Javascript based UDF for a nested level interval addition query is way better than the SQL based UDF.
What might be the reason that attributes to the huge performance difference?