Skip to content

Commit

Permalink
feat: Add missing Redshift conversion functions
Browse files Browse the repository at this point in the history
Signed-off-by: Andreas Reichel <andreas@manticore-projects.com>
  • Loading branch information
manticore-projects committed May 4, 2024
1 parent e63ac78 commit 649edd4
Show file tree
Hide file tree
Showing 6 changed files with 115 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import net.sf.jsqlparser.expression.StructType;
import net.sf.jsqlparser.expression.TimeKeyExpression;
import net.sf.jsqlparser.expression.TimezoneExpression;
import net.sf.jsqlparser.expression.TranscodingFunction;
import net.sf.jsqlparser.expression.WhenClause;
import net.sf.jsqlparser.expression.WindowDefinition;
import net.sf.jsqlparser.expression.operators.arithmetic.Addition;
Expand Down Expand Up @@ -2122,6 +2123,11 @@ public void visit(LikeExpression likeExpression) {
super.visit(likeExpression);
}

public void visit(TranscodingFunction function) {
CastExpression castExpression = new CastExpression("Cast", function.getExpression(), function.getColDataType().toString());
castExpression.accept(this);
}

public static boolean isEmpty(Collection<?> collection) {
return collection == null || collection.isEmpty();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import net.sf.jsqlparser.expression.WhenClause;
import net.sf.jsqlparser.expression.operators.arithmetic.Addition;
import net.sf.jsqlparser.expression.operators.arithmetic.Subtraction;
import net.sf.jsqlparser.expression.operators.relational.EqualsTo;
import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
import net.sf.jsqlparser.expression.operators.relational.GreaterThan;
import net.sf.jsqlparser.expression.operators.relational.MinorThan;
Expand Down Expand Up @@ -70,7 +71,7 @@ enum TranspiledFunction {

, TRUNC

, TO_CHAR
, TO_CHAR, TO_NUMBER, CONVERT

, APPROXIMATE_PERCENTILE_DISC, APPROXIMATE_COUNT

Expand Down Expand Up @@ -512,6 +513,33 @@ public void visit(Function function) {
function.setParameters(parameters.get(0), stringValue);
}
break;
case TO_NUMBER:
// list_aggregate(regexp_extract_all('-1,000.00', '[\+|\-\d|\.]'),'string_agg', '')::NUMERIC
Function f1 = new Function(
"List_Aggregate"
, new Function("Regexp_Extract_All", parameters.get(0), new StringValue("[\\+|\\-\\d|\\.]"))
, new StringValue("string_agg")
, new StringValue("")
);
f1 = new Function("If"
, new EqualsTo(new Function("TypeOf", parameters.get(0)), new StringValue("VARCHAR"))
, f1
, parameters.get(0)
);
switch (paramCount) {
case 2:
warning("Format Parameter not supported.");
rewrittenExpression =
new CastExpression(functionName.startsWith("TRY") ? "Try_Cast" : "Cast",
f1, "NUMERIC");
break;
case 1:
rewrittenExpression =
new CastExpression(functionName.startsWith("TRY") ? "Try_Cast" : "Cast",
f1, "NUMERIC");
break;
}
break;
case ARRAY:
rewrittenExpression = new ArrayConstructor(parameters, false);
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import net.sf.jsqlparser.expression.TimezoneExpression;
import net.sf.jsqlparser.expression.WhenClause;
import net.sf.jsqlparser.expression.operators.arithmetic.Subtraction;
import net.sf.jsqlparser.expression.operators.relational.EqualsTo;
import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
import net.sf.jsqlparser.expression.operators.relational.GreaterThan;
import net.sf.jsqlparser.expression.operators.relational.IsNullExpression;
Expand Down Expand Up @@ -836,6 +837,20 @@ public void visit(Function function) {
case TRY_TO_NUMBER:
case TRY_TO_NUMERIC:
// TO_DECIMAL( <expr> [, '<format>' ] [, <precision> [, <scale> ] ] )
// list_aggregate(regexp_extract_all('-1,000.00', '[\+|\-\d|\.]'),'string_agg', '')::NUMERIC

Function f1 = new Function(
"List_Aggregate"
, new Function("Regexp_Extract_All", parameters.get(0), new StringValue("[\\+|\\-\\d|\\.]"))
, new StringValue("string_agg")
, new StringValue("")
);
f1 = new Function("If"
, new EqualsTo(new Function("TypeOf", parameters.get(0)), new StringValue("VARCHAR"))
, f1
, parameters.get(0)
);

switch (paramCount) {
case 4:
warning("Format Parameter not supported.");
Expand All @@ -845,7 +860,7 @@ public void visit(Function function) {
+ ((LongValue) parameters.get(3)).getValue() + ")";
rewrittenExpression =
new CastExpression(functionName.startsWith("TRY") ? "Try_Cast" : "Cast",
parameters.get(0), typeStr);
f1, typeStr);
}
break;
case 3:
Expand All @@ -855,30 +870,33 @@ public void visit(Function function) {
String typeStr = "DECIMAL(" + ((LongValue) parameters.get(2)).getValue() + ")";
rewrittenExpression =
new CastExpression(functionName.startsWith("TRY") ? "Try_Cast" : "Cast",
parameters.get(0), typeStr);
f1, typeStr);
} else if (parameters.get(1) instanceof LongValue
&& parameters.get(2) instanceof LongValue) {
String typeStr = "DECIMAL(" + ((LongValue) parameters.get(1)).getValue() + ", "
+ ((LongValue) parameters.get(2)).getValue() + ")";
rewrittenExpression =
new CastExpression(functionName.startsWith("TRY") ? "Try_Cast" : "Cast",
parameters.get(0), typeStr);
f1, typeStr);
}
break;
case 2:
if (parameters.get(1) instanceof StringValue) {
warning("Format Parameter not supported.");
rewrittenExpression =
new CastExpression(functionName.startsWith("TRY") ? "Try_Cast" : "Cast",
f1, "DECIMAL(12,0)");
} else if (parameters.get(1) instanceof LongValue) {
String typeStr = "DECIMAL(" + ((LongValue) parameters.get(1)).getValue() + ")";
rewrittenExpression =
new CastExpression(functionName.startsWith("TRY") ? "Try_Cast" : "Cast",
parameters.get(0), typeStr);
f1, typeStr);
}
break;
case 1:
rewrittenExpression =
new CastExpression(functionName.startsWith("TRY") ? "Try_Cast" : "Cast",
parameters.get(0), "DECIMAL(12,0)");
f1, "DECIMAL(12,0)");
break;
}
break;
Expand Down
Binary file modified src/main/resources/doc/JSQLTranspiler.ods
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
-- provided
SELECT CONVERT(time, saletime) AS time, salesid
FROM sales order by salesid limit 10;

-- expected
SELECT Cast(saletime AS time) AS time, salesid
FROM sales order by salesid limit 10;

-- result
"time","salesid"
"02:36:48","1"
"05:00:16","2"
"08:26:17","3"
"08:38:52","4"
"09:17:02","5"
"11:59:24","6"
"12:56:06","7"
"02:12:36","8"
"02:23:17","9"
"02:51:55","10"


-- provided
select to_number('-12,454.8', 'S99G999D9') AS number;

-- expected
SELECT CAST(IF(TYPEOF('-12,454.8')='VARCHAR',LIST_AGGREGATE(REGEXP_EXTRACT_ALL('-12,454.8','[\+|\-\D|\.]'),'string_agg',''),'-12,454.8')AS NUMERIC) AS number;

-- result
"number"
"-12454.800"

-- provided
select to_number('$ 12,454.88', 'L 99G999D99') AS number;

-- expected
SELECT CAST(IF(TYPEOF('$ 12,454.88')='VARCHAR',LIST_AGGREGATE(REGEXP_EXTRACT_ALL('$ 12,454.88','[\+|\-\D|\.]'),'string_agg',''),'$ 12,454.88')AS NUMERIC) AS number;

-- result
"number"
"12454.880"

-- provided
select to_number('$ 2,012,454.88', 'L 9,999,999.99') AS number;

-- expected
SELECT CAST(IF(TYPEOF('$ 2,012,454.88')='VARCHAR',LIST_AGGREGATE(REGEXP_EXTRACT_ALL('$ 2,012,454.88','[\+|\-\D|\.]'),'string_agg',''),'$ 2,012,454.88')AS NUMERIC) AS number;

-- result
"number"
"2012454.880"
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,12 @@ SELECT expr,
FROM number_conv;

-- expected
SELECT EXPR
,CAST(EXPR AS DECIMAL(12,0))AS N1
,CAST(EXPR AS DECIMAL(10,1))AS N2
,CAST(EXPR AS DECIMAL(10,8))AS N3
FROM NUMBER_CONV;
SELECT expr
, Cast( If( Typeof( expr ) = 'VARCHAR', List_Aggregate( Regexp_Extract_All( expr, '[\+|\-\D|\.]' ), 'string_agg', '' ), expr ) AS DECIMAL (12, 0) ) AS n1
, Cast( If( Typeof( expr ) = 'VARCHAR', List_Aggregate( Regexp_Extract_All( expr, '[\+|\-\D|\.]' ), 'string_agg', '' ), expr ) AS DECIMAL (10, 1) ) AS n2
, Cast( If( Typeof( expr ) = 'VARCHAR', List_Aggregate( Regexp_Extract_All( expr, '[\+|\-\D|\.]' ), 'string_agg', '' ), expr ) AS DECIMAL (10, 8) ) AS n3
FROM number_conv
;

-- result
"expr","N1","N2","N3"
Expand Down

0 comments on commit 649edd4

Please sign in to comment.