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

Skip to content

Commit 777731d

Browse files
committed
script filter support
1 parent 2c9b063 commit 777731d

File tree

6 files changed

+166
-2
lines changed

6 files changed

+166
-2
lines changed

src/main/java/org/nlpcn/es4sql/domain/Condition.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
public class Condition extends Where {
1818

1919
public enum OPEAR {
20-
EQ, GT, LT, GTE, LTE, N, LIKE, NLIKE, IS, ISN, IN, NIN , BETWEEN ,NBETWEEN , GEO_INTERSECTS , GEO_BOUNDING_BOX , GEO_DISTANCE , GEO_DISTANCE_RANGE, GEO_POLYGON , GEO_CELL, IN_TERMS , TERM , IDS_QUERY,NESTED_COMPLEX;
20+
EQ, GT, LT, GTE, LTE, N, LIKE, NLIKE, IS, ISN, IN, NIN , BETWEEN ,NBETWEEN , GEO_INTERSECTS , GEO_BOUNDING_BOX , GEO_DISTANCE , GEO_DISTANCE_RANGE, GEO_POLYGON , GEO_CELL, IN_TERMS , TERM , IDS_QUERY,NESTED_COMPLEX , SCRIPT;
2121

2222
public static Map<String,OPEAR> methodNameToOpear;
2323

@@ -164,6 +164,9 @@ public Condition(CONN conn, String name, String oper, Object value,boolean isNes
164164
case "NESTED":
165165
this.opear = OPEAR.NESTED_COMPLEX;
166166
break;
167+
case "SCRIPT":
168+
this.opear = OPEAR.SCRIPT;
169+
break;
167170
default:
168171
throw new SqlParseException(oper + " is err!");
169172
}
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
package org.nlpcn.es4sql.parse;
2+
3+
import com.alibaba.druid.sql.ast.SQLExpr;
4+
import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr;
5+
import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr;
6+
import org.nlpcn.es4sql.Util;
7+
import org.nlpcn.es4sql.domain.Field;
8+
import org.nlpcn.es4sql.domain.KVValue;
9+
import org.nlpcn.es4sql.exception.SqlParseException;
10+
11+
import java.util.ArrayList;
12+
import java.util.HashMap;
13+
import java.util.List;
14+
import java.util.Map;
15+
16+
/**
17+
* Created by Eliran on 11/12/2015.
18+
*/
19+
public class ScriptFilter {
20+
private String script;
21+
private Map<String,Object> args;
22+
23+
public ScriptFilter() {
24+
args = null;
25+
}
26+
27+
public ScriptFilter(String script, Map<String, Object> args) {
28+
this.script = script;
29+
this.args = args;
30+
}
31+
32+
public boolean tryParseFromMethodExpr(SQLMethodInvokeExpr expr) throws SqlParseException {
33+
if (!expr.getMethodName().toLowerCase().equals("script")) {
34+
return false;
35+
}
36+
List<SQLExpr> methodParameters = expr.getParameters();
37+
if (methodParameters.size() == 0) {
38+
return false;
39+
}
40+
script = Util.extendedToString(methodParameters.get(0));
41+
42+
if (methodParameters.size() == 1) {
43+
return true;
44+
}
45+
46+
args = new HashMap<>();
47+
for (int i = 1; i < methodParameters.size(); i++) {
48+
49+
SQLExpr innerExpr = methodParameters.get(i);
50+
if (!(innerExpr instanceof SQLBinaryOpExpr)) {
51+
return false;
52+
}
53+
SQLBinaryOpExpr binaryOpExpr = (SQLBinaryOpExpr) innerExpr;
54+
if (!binaryOpExpr.getOperator().getName().equals("=")) {
55+
return false;
56+
}
57+
58+
SQLExpr right = binaryOpExpr.getRight();
59+
Object value = Util.expr2Object(right);
60+
String key = Util.extendedToString(binaryOpExpr.getLeft());
61+
args.put(key, value);
62+
63+
}
64+
return true;
65+
}
66+
67+
public boolean containsParameters(){
68+
return args!=null && args.size() > 0;
69+
}
70+
71+
public String getScript() {
72+
return script;
73+
}
74+
75+
76+
public Map<String, Object> getArgs() {
77+
return args;
78+
}
79+
80+
}

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock;
1010

1111

12+
import org.nlpcn.es4sql.Util;
1213
import org.nlpcn.es4sql.domain.*;
1314
import org.nlpcn.es4sql.domain.Where.CONN;
1415
import org.nlpcn.es4sql.domain.hints.Hint;
@@ -201,6 +202,14 @@ else if (methodName.toLowerCase().equals("nested")){
201202
where.addWhere(condition);
202203

203204
}
205+
else if (methodName.toLowerCase().equals("script")){
206+
ScriptFilter scriptFilter = new ScriptFilter();
207+
if(!scriptFilter.tryParseFromMethodExpr(methodExpr)){
208+
throw new SqlParseException("could not parse script filter");
209+
}
210+
Condition condition = new Condition(CONN.valueOf(opear),null,"SCRIPT",scriptFilter);
211+
where.addWhere(condition);
212+
}
204213
else {
205214
throw new SqlParseException("unsupported method: " + methodName);
206215
}

src/main/java/org/nlpcn/es4sql/query/maker/Maker.java

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
package org.nlpcn.es4sql.query.maker;
22

33
import java.io.IOException;
4+
import java.util.ArrayList;
5+
import java.util.List;
46
import java.util.Set;
57

8+
import com.alibaba.druid.sql.ast.SQLExpr;
69
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
710
import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr;
811
import org.elasticsearch.common.collect.Sets;
@@ -12,13 +15,16 @@
1215
import org.elasticsearch.common.xcontent.XContentParser;
1316
import org.elasticsearch.common.xcontent.json.JsonXContent;
1417
import org.elasticsearch.index.query.*;
18+
import org.nlpcn.es4sql.Util;
1519
import org.nlpcn.es4sql.domain.Condition;
1620
import org.nlpcn.es4sql.domain.Condition.OPEAR;
1721
import org.nlpcn.es4sql.domain.Paramer;
22+
import org.nlpcn.es4sql.domain.Query;
1823
import org.nlpcn.es4sql.domain.Where;
1924
import org.nlpcn.es4sql.exception.SqlParseException;
2025

2126

27+
import org.nlpcn.es4sql.parse.ScriptFilter;
2228
import org.nlpcn.es4sql.parse.SubQueryExpression;
2329
import org.nlpcn.es4sql.spatial.*;
2430

@@ -317,7 +323,20 @@ private ToXContent make(Condition cond, String name, Object value) throws SqlPar
317323
x = FilterBuilders.nestedFilter(name,nestedFilter);
318324
}
319325
break;
320-
default:
326+
case SCRIPT:
327+
ScriptFilter scriptFilter = (ScriptFilter) value;
328+
if(isQuery) {
329+
throw new SqlParseException("script on where is only for filter");
330+
}
331+
else {
332+
ScriptFilterBuilder scriptFilterBuilder = FilterBuilders.scriptFilter(scriptFilter.getScript());
333+
if(scriptFilter.containsParameters()){
334+
scriptFilterBuilder.params(scriptFilter.getArgs());
335+
}
336+
x = scriptFilterBuilder;
337+
}
338+
break;
339+
default:
321340
throw new SqlParseException("not define type " + cond.getName());
322341
}
323342

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

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -814,6 +814,24 @@ public void multipleIndicesOneNotExistWithoutHint() throws IOException, SqlParse
814814
Assert.assertTrue(response.getTotalHits() > 0);
815815
}
816816

817+
//todo: find a way to check if scripts are enabled , uncomment before deploy.
818+
// @Test
819+
// public void scriptFilterNoParams() throws IOException, SqlParseException, SQLFeatureNotSupportedException{
820+
// SearchHits response = query(String.format("SELECT insert_time FROM %s/online where script('doc[\\'insert_time\''].date.hourOfDay==16') " +
821+
// "and insert_time <'2014-08-21T00:00:00.000Z'", TEST_INDEX));
822+
// Assert.assertEquals(237,response.getTotalHits() );
823+
//
824+
// }
825+
//
826+
// @Test
827+
// public void scriptFilterWithParams() throws IOException, SqlParseException, SQLFeatureNotSupportedException{
828+
// SearchHits response = query(String.format("SELECT insert_time FROM %s/online where script('doc[\\'insert_time\''].date.hourOfDay==x','x'=16) " +
829+
// "and insert_time <'2014-08-21T00:00:00.000Z'", TEST_INDEX));
830+
// Assert.assertEquals(237,response.getTotalHits() );
831+
//
832+
// }
833+
834+
817835
private SearchHits query(String query) throws SqlParseException, SQLFeatureNotSupportedException, SQLFeatureNotSupportedException {
818836
SearchDao searchDao = MainTestSuite.getSearchDao();
819837
SqlElasticSearchRequestBuilder select = (SqlElasticSearchRequestBuilder) searchDao.explain(query);

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

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import com.alibaba.druid.sql.ast.expr.SQLIntegerExpr;
55
import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr;
66
import com.alibaba.druid.sql.ast.expr.SQLQueryExpr;
7+
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock;
78
import org.elasticsearch.index.query.BoolFilterBuilder;
89
import org.junit.Assert;
910
import org.junit.BeforeClass;
@@ -13,6 +14,8 @@
1314
import org.nlpcn.es4sql.domain.hints.HintType;
1415
import org.nlpcn.es4sql.exception.SqlParseException;
1516
import org.nlpcn.es4sql.parse.ElasticSqlExprParser;
17+
import org.nlpcn.es4sql.parse.FieldMaker;
18+
import org.nlpcn.es4sql.parse.ScriptFilter;
1619
import org.nlpcn.es4sql.parse.SqlParser;
1720
import org.nlpcn.es4sql.query.maker.FilterMaker;
1821

@@ -725,6 +728,38 @@ public void complexNestedTest() throws SqlParseException {
725728
Assert.assertEquals(2,where.getWheres().size());
726729
}
727730

731+
@Test
732+
public void scriptOnFilterNoParams() throws SqlParseException {
733+
String query = "select * from x where script('doc[\\'field\\'].date.hourOfDay == 3') ";
734+
Select select = parser.parseSelect((SQLQueryExpr) queryToExpr(query));
735+
Condition condition = (Condition) select.getWhere().getWheres().get(0);
736+
Assert.assertEquals(Condition.OPEAR.SCRIPT,condition.getOpear());
737+
Assert.assertEquals(null,condition.getName());
738+
Assert.assertTrue(condition.getValue() instanceof ScriptFilter);
739+
ScriptFilter scriptFilter = (ScriptFilter) condition.getValue();
740+
Assert.assertEquals("doc['field'].date.hourOfDay == 3",scriptFilter.getScript());
741+
Assert.assertFalse(scriptFilter.containsParameters());
742+
}
743+
744+
@Test
745+
public void scriptOnFilterWithParams() throws SqlParseException {
746+
String query = "select * from x where script('doc[\\'field\\'].date.hourOfDay == x','x'=3) ";
747+
Select select = parser.parseSelect((SQLQueryExpr) queryToExpr(query));
748+
Condition condition = (Condition) select.getWhere().getWheres().get(0);
749+
Assert.assertEquals(Condition.OPEAR.SCRIPT,condition.getOpear());
750+
Assert.assertEquals(null,condition.getName());
751+
Assert.assertTrue(condition.getValue() instanceof ScriptFilter);
752+
ScriptFilter scriptFilter = (ScriptFilter) condition.getValue();
753+
Assert.assertEquals("doc['field'].date.hourOfDay == x",scriptFilter.getScript());
754+
Assert.assertTrue(scriptFilter.containsParameters());
755+
Map<String, Object> args = scriptFilter.getArgs();
756+
Assert.assertEquals(1, args.size());
757+
Assert.assertTrue(args.containsKey("x"));
758+
Assert.assertEquals(3, args.get("x"));
759+
760+
}
761+
762+
728763

729764
private SQLExpr queryToExpr(String query) {
730765
return new ElasticSqlExprParser(query).expr();

0 commit comments

Comments
 (0)