Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit f55f153

Browse files
authored
Merge pull request NLPchina#514 from leonlu001/master
new feature: cast
2 parents c009155 + 976f614 commit f55f153

File tree

3 files changed

+201
-0
lines changed

3 files changed

+201
-0
lines changed
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package org.nlpcn.es4sql.parse;
2+
3+
import com.alibaba.druid.sql.ast.expr.SQLCastExpr;
4+
import com.google.common.base.Joiner;
5+
import org.nlpcn.es4sql.SQLFunctions;
6+
import org.nlpcn.es4sql.Util;
7+
import org.nlpcn.es4sql.exception.SqlParseException;
8+
9+
import java.util.ArrayList;
10+
import java.util.List;
11+
12+
/**
13+
* Created by leonlu on 2017/9/21.
14+
*/
15+
public class CastParser {
16+
17+
private enum DataType {
18+
INT, LONG, FLOAT, DOUBLE, STRING, DATETIME
19+
}
20+
21+
private SQLCastExpr castExpr;
22+
private String alias;
23+
private String tableAlias;
24+
25+
public CastParser(SQLCastExpr castExpr, String alias, String tableAlias) {
26+
this.castExpr = castExpr;
27+
this.alias = alias;
28+
this.tableAlias = tableAlias;
29+
}
30+
31+
public String parse(boolean isReturn) throws SqlParseException {
32+
List<String> result = new ArrayList<>();
33+
34+
String dataType = castExpr.getDataType().getName().toUpperCase();
35+
String fileName = String.format("doc['%s'].value",Util.expr2Object(castExpr.getExpr()));
36+
String name = "field_"+SQLFunctions.random();
37+
38+
try {
39+
if (DataType.valueOf(dataType) == DataType.INT) {
40+
result.add(String.format("def %s = Double.parseDouble(%s.toString()).intValue()", name, fileName));
41+
} else if (DataType.valueOf(dataType) == DataType.LONG) {
42+
result.add(String.format("def %s = Double.parseDouble(%s.toString()).longValue()", name, fileName));
43+
} else if (DataType.valueOf(dataType) == DataType.FLOAT) {
44+
result.add(String.format("def %s = Double.parseDouble(%s.toString()).floatValue()", name, fileName));
45+
} else if (DataType.valueOf(dataType) == DataType.DOUBLE) {
46+
result.add(String.format("def %s = Double.parseDouble(%s.toString()).doubleValue()", name, fileName));
47+
} else if (DataType.valueOf(dataType) == DataType.STRING) {
48+
result.add(String.format("def %s = %s.toString()",name, fileName));
49+
} else if (DataType.valueOf(dataType) == DataType.DATETIME) {
50+
result.add(String.format("def %s = new Date(Double.parseDouble(%s.toString()).longValue())", name, fileName));
51+
} else {
52+
throw new SqlParseException("not support cast to data type:" + dataType);
53+
}
54+
if(isReturn) {
55+
result.add("return " + name);
56+
}
57+
58+
return Joiner.on("; ").join(result);
59+
} catch (Exception ex) {
60+
throw new SqlParseException(String.format("field cast to type: %s failed. error:%s",dataType, ex.getMessage()));
61+
}
62+
}
63+
}

src/main/java/org/nlpcn/es4sql/parse/FieldMaker.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,16 @@ public static Field makeField(SQLExpr expr, String alias, String tableAlias) thr
6161
methodParameters.add(new KVValue(alias));
6262
methodParameters.add(new KVValue(scriptCode));
6363
return new MethodField("script", methodParameters, null, alias);
64+
}else if (expr instanceof SQLCastExpr) {
65+
SQLCastExpr castExpr = (SQLCastExpr) expr;
66+
if (alias == null) {
67+
alias = "cast_" + castExpr.getExpr().toString();
68+
}
69+
String scriptCode = new CastParser(castExpr, alias, tableAlias).parse(true);
70+
List<KVValue> methodParameters = new ArrayList<>();
71+
methodParameters.add(new KVValue(alias));
72+
methodParameters.add(new KVValue(scriptCode));
73+
return new MethodField("script", methodParameters, null, alias);
6474
} else {
6575
throw new SqlParseException("unknown field name : " + expr);
6676
}
@@ -251,6 +261,9 @@ public static MethodField makeMethodField(String name, List<SQLExpr> arguments,
251261
} else if (object instanceof SQLCaseExpr) {
252262
String scriptCode = new CaseWhenParser((SQLCaseExpr) object, alias, tableAlias).parse();
253263
paramers.add(new KVValue("script",new SQLCharExpr(scriptCode)));
264+
} else if(object instanceof SQLCastExpr) {
265+
String scriptCode = new CastParser((SQLCastExpr) object, alias, tableAlias).parse(false);
266+
paramers.add(new KVValue("script",new SQLCharExpr(scriptCode)));
254267
} else {
255268
paramers.add(new KVValue(Util.removeTableAilasFromField(object, tableAlias)));
256269
}

src/test/java/org/nlpcn/es4sql/SqlParserTests.java

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -986,6 +986,131 @@ public void caseWhenTestWithouhtElseExpr() throws SqlParseException {
986986

987987
}
988988

989+
@Test
990+
public void castToIntTest() throws Exception {
991+
String query = "select cast(age as int) from "+ TestsConstants.TEST_INDEX + "/account limit 10";
992+
SQLExpr sqlExpr = queryToExpr(query);
993+
Select select = parser.parseSelect((SQLQueryExpr) sqlExpr);
994+
Field castField = select.getFields().get(0);
995+
Assert.assertTrue(castField instanceof MethodField);
996+
997+
MethodField methodField = (MethodField) castField;
998+
Assert.assertEquals("script",castField.getName());
999+
1000+
String alias = (String) methodField.getParams().get(0).value;
1001+
String scriptCode = (String) methodField.getParams().get(1).value;
1002+
Assert.assertEquals("cast_age",alias);
1003+
Assert.assertTrue(scriptCode.contains("doc['age'].value"));
1004+
Assert.assertTrue(scriptCode.contains("Double.parseDouble(doc['age'].value.toString()).intValue()"));
1005+
}
1006+
1007+
@Test
1008+
public void castToLongTest() throws Exception {
1009+
String query = "select cast(insert_time as long) from "+ TestsConstants.TEST_INDEX + " limit 10";
1010+
SQLExpr sqlExpr = queryToExpr(query);
1011+
Select select = parser.parseSelect((SQLQueryExpr) sqlExpr);
1012+
Field castField = select.getFields().get(0);
1013+
Assert.assertTrue(castField instanceof MethodField);
1014+
1015+
MethodField methodField = (MethodField) castField;
1016+
Assert.assertEquals("script",castField.getName());
1017+
1018+
String alias = (String) methodField.getParams().get(0).value;
1019+
String scriptCode = (String) methodField.getParams().get(1).value;
1020+
Assert.assertEquals("cast_insert_time",alias);
1021+
Assert.assertTrue(scriptCode.contains("doc['insert_time'].value"));
1022+
Assert.assertTrue(scriptCode.contains("Double.parseDouble(doc['insert_time'].value.toString()).longValue()"));
1023+
}
1024+
1025+
@Test
1026+
public void castToFloatTest() throws Exception {
1027+
String query = "select cast(age as float) from "+ TestsConstants.TEST_INDEX + " limit 10";
1028+
SQLExpr sqlExpr = queryToExpr(query);
1029+
Select select = parser.parseSelect((SQLQueryExpr) sqlExpr);
1030+
Field castField = select.getFields().get(0);
1031+
Assert.assertTrue(castField instanceof MethodField);
1032+
1033+
MethodField methodField = (MethodField) castField;
1034+
Assert.assertEquals("script",castField.getName());
1035+
1036+
String alias = (String) methodField.getParams().get(0).value;
1037+
String scriptCode = (String) methodField.getParams().get(1).value;
1038+
Assert.assertEquals("cast_age",alias);
1039+
Assert.assertTrue(scriptCode.contains("doc['age'].value"));
1040+
Assert.assertTrue(scriptCode.contains("Double.parseDouble(doc['age'].value.toString()).floatValue()"));
1041+
}
1042+
1043+
@Test
1044+
public void castToDoubleTest() throws Exception {
1045+
String query = "select cast(age as double) from "+ TestsConstants.TEST_INDEX + "/account limit 10";
1046+
SQLExpr sqlExpr = queryToExpr(query);
1047+
Select select = parser.parseSelect((SQLQueryExpr) sqlExpr);
1048+
Field castField = select.getFields().get(0);
1049+
Assert.assertTrue(castField instanceof MethodField);
1050+
1051+
MethodField methodField = (MethodField) castField;
1052+
Assert.assertEquals("script",castField.getName());
1053+
1054+
String alias = (String) methodField.getParams().get(0).value;
1055+
String scriptCode = (String) methodField.getParams().get(1).value;
1056+
Assert.assertEquals("cast_age",alias);
1057+
Assert.assertTrue(scriptCode.contains("doc['age'].value"));
1058+
Assert.assertTrue(scriptCode.contains("Double.parseDouble(doc['age'].value.toString()).doubleValue()"));
1059+
}
1060+
1061+
@Test
1062+
public void castToStringTest() throws Exception {
1063+
String query = "select cast(age as string) from "+ TestsConstants.TEST_INDEX + "/account limit 10";
1064+
SQLExpr sqlExpr = queryToExpr(query);
1065+
Select select = parser.parseSelect((SQLQueryExpr) sqlExpr);
1066+
Field castField = select.getFields().get(0);
1067+
Assert.assertTrue(castField instanceof MethodField);
1068+
1069+
MethodField methodField = (MethodField) castField;
1070+
Assert.assertEquals("script",castField.getName());
1071+
1072+
String alias = (String) methodField.getParams().get(0).value;
1073+
String scriptCode = (String) methodField.getParams().get(1).value;
1074+
Assert.assertEquals("cast_age",alias);
1075+
Assert.assertTrue(scriptCode.contains("doc['age'].value.toString()"));
1076+
}
1077+
1078+
@Test
1079+
public void castToDateTimeTest() throws Exception {
1080+
String query = "select cast(age as datetime) from "+ TestsConstants.TEST_INDEX + "/account limit 10";
1081+
SQLExpr sqlExpr = queryToExpr(query);
1082+
Select select = parser.parseSelect((SQLQueryExpr) sqlExpr);
1083+
Field castField = select.getFields().get(0);
1084+
Assert.assertTrue(castField instanceof MethodField);
1085+
1086+
MethodField methodField = (MethodField) castField;
1087+
Assert.assertEquals("script",castField.getName());
1088+
1089+
String alias = (String) methodField.getParams().get(0).value;
1090+
String scriptCode = (String) methodField.getParams().get(1).value;
1091+
Assert.assertEquals("cast_age",alias);
1092+
Assert.assertTrue(scriptCode.contains("doc['age'].value"));
1093+
Assert.assertTrue(scriptCode.contains("new Date(Double.parseDouble(doc['age'].value.toString()).longValue())"));
1094+
}
1095+
1096+
@Test
1097+
public void castToDoubleThenDivideTest() throws Exception {
1098+
String query = "select cast(age as double)/2 from "+ TestsConstants.TEST_INDEX + "/account limit 10";
1099+
SQLExpr sqlExpr = queryToExpr(query);
1100+
Select select = parser.parseSelect((SQLQueryExpr) sqlExpr);
1101+
Field castField = select.getFields().get(0);
1102+
Assert.assertTrue(castField instanceof MethodField);
1103+
1104+
MethodField methodField = (MethodField) castField;
1105+
Assert.assertEquals("script",castField.getName());
1106+
1107+
String alias = (String) methodField.getParams().get(0).value;
1108+
String scriptCode = (String) methodField.getParams().get(1).value;
1109+
Assert.assertTrue(scriptCode.contains("doc['age'].value"));
1110+
Assert.assertTrue(scriptCode.contains("Double.parseDouble(doc['age'].value.toString()).doubleValue()"));
1111+
Assert.assertTrue(scriptCode.contains("/ 2"));
1112+
}
1113+
9891114

9901115
@Test
9911116
public void multiSelectMinusOperationCheckIndices() throws SqlParseException {

0 commit comments

Comments
 (0)