Skip to content

Commit

Permalink
fix: Safe divide shall return NULL on division by Zero
Browse files Browse the repository at this point in the history
- fixes #56

Signed-off-by: Andreas Reichel <[email protected]>
Signed-off-by: manticore-projects <[email protected]>
  • Loading branch information
manticore-projects committed Dec 7, 2024
1 parent fbcd664 commit 86fc552
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 10 deletions.
26 changes: 18 additions & 8 deletions src/main/java/ai/starlake/transpiler/JSQLExpressionTranspiler.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import net.sf.jsqlparser.expression.CaseExpression;
import net.sf.jsqlparser.expression.CastExpression;
import net.sf.jsqlparser.expression.DateTimeLiteralExpression;
import net.sf.jsqlparser.expression.DoubleValue;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.ExpressionVisitorAdapter;
import net.sf.jsqlparser.expression.ExtractExpression;
Expand All @@ -46,10 +47,12 @@
import net.sf.jsqlparser.expression.WindowDefinition;
import net.sf.jsqlparser.expression.operators.arithmetic.Addition;
import net.sf.jsqlparser.expression.operators.arithmetic.Concat;
import net.sf.jsqlparser.expression.operators.arithmetic.Division;
import net.sf.jsqlparser.expression.operators.arithmetic.Multiplication;
import net.sf.jsqlparser.expression.operators.relational.EqualsTo;
import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
import net.sf.jsqlparser.expression.operators.relational.InExpression;
import net.sf.jsqlparser.expression.operators.relational.IsNullExpression;
import net.sf.jsqlparser.expression.operators.relational.LikeExpression;
import net.sf.jsqlparser.expression.operators.relational.MinorThanEquals;
import net.sf.jsqlparser.expression.operators.relational.ParenthesedExpressionList;
Expand Down Expand Up @@ -906,8 +909,15 @@ THEN Instr( source_value, Regexp_Extract( source_value, reg_exp ) )
}
}
break;
case SAFE_ADD:
case SAFE_DIVIDE:
Expression p0 = parameters.get(0);
Expression p1 = parameters.get(1);
Expression orExpression = BinaryExpression.or(new EqualsTo(p1, new DoubleValue(0)),
new IsNullExpression(p1), new IsNullExpression(p0));
rewrittenExpression = new Function("If", orExpression, new NullValue(),
new Division(parameters.get(0), parameters.get(1)));
break;
case SAFE_ADD:
case SAFE_MULTIPLY:
case SAFE_SUBTRACT:
warning("SAFE variant not supported");
Expand Down Expand Up @@ -982,13 +992,13 @@ public <K> Void visit(Column column, K params) {
if (parameters != null) {
switch (parameters.size()) {
case 3:
Expression p1 = parameters.get(0);
Expression p2 = parameters.get(1);
p0 = parameters.get(0);
p1 = parameters.get(1);

// turn it into a Lambda replacing the NULL values with 3rd parameter
p1 = new Function("List_Transform", p1, new LambdaExpression("x",
p0 = new Function("List_Transform", p0, new LambdaExpression("x",
new Function("Coalesce", new Column("x"), parameters.get(2))));
function.setParameters(p1, p2);
function.setParameters(p0, p1);
}
}
break;
Expand Down Expand Up @@ -1222,19 +1232,19 @@ ELSE JSON_VALUE('{"a.b":{"c":"world"}}','$."a.b".c')
*/
switch (paramCount) {
case 2:
Expression p1 = parameters.get(1);
p1 = parameters.get(1);
if (p1 instanceof StringValue) {
String jsonPath = ((StringValue) parameters.get(1)).getValue();
if (jsonPath.trim().equalsIgnoreCase("$")) {
function.setParameters(parameters.get(0), new StringValue("$"));
} else {
jsonPath = jsonPath.replaceAll("\\$\\[([^]]+)]", "\\$.$1");
jsonPath = jsonPath.replaceAll("\\[\"(.*?)\"\\]", "\"$1\"");
jsonPath = jsonPath.replaceAll("\\[\"(.*?)\"]", "\"$1\"");
p1 = new StringValue(jsonPath);
}
}

ParenthesedExpressionList types = new ParenthesedExpressionList(
ParenthesedExpressionList<?> types = new ParenthesedExpressionList<>(
new StringValue("VARCHAR"), new StringValue("DOUBLE"), new StringValue("BOOLEAN"),
new StringValue("UBIGINT"), new StringValue("BIGINT"));
rewrittenExpression =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -356,11 +356,11 @@ SELECT /* Approximation: SAFE variant not supported */ ADD(5, 4) a;
SELECT SAFE_DIVIDE(5, 4) a;

-- expected
SELECT /* Approximation: SAFE variant not supported */ DIVIDE(5, 4) a;
SELECT IF(4=0.0 OR 4 IS NULL OR 5 IS NULL,NULL,5/4)A;

-- result
"a"
"1"
"1.25"


-- provided
Expand Down

0 comments on commit 86fc552

Please sign in to comment.