14
14
import org .nlpcn .es4sql .domain .hints .Hint ;
15
15
import org .nlpcn .es4sql .domain .hints .HintFactory ;
16
16
import org .nlpcn .es4sql .exception .SqlParseException ;
17
+ import org .nlpcn .es4sql .query .join .NestedLoopsElasticRequestBuilder ;
17
18
import org .nlpcn .es4sql .spatial .SpatialParamsFactory ;
18
19
19
20
/**
@@ -80,10 +81,18 @@ private Where findWhere(SQLExpr where) throws SqlParseException {
80
81
81
82
82
83
private boolean isCond (SQLBinaryOpExpr expr ) {
83
- return expr .getLeft () instanceof SQLIdentifierExpr || expr .getLeft () instanceof SQLPropertyExpr || expr .getLeft () instanceof SQLVariantRefExpr ;
84
+ SQLExpr leftSide = expr .getLeft ();
85
+ if (leftSide instanceof SQLMethodInvokeExpr ){
86
+ return isAllowedMethodOnConditionLeft ((SQLMethodInvokeExpr ) leftSide );
87
+ }
88
+ return leftSide instanceof SQLIdentifierExpr || leftSide instanceof SQLPropertyExpr || leftSide instanceof SQLVariantRefExpr ;
84
89
}
85
90
86
- private void parseWhere (SQLExpr expr , Where where ) throws SqlParseException {
91
+ private boolean isAllowedMethodOnConditionLeft (SQLMethodInvokeExpr method ) {
92
+ return method .getMethodName ().toLowerCase ().equals ("nested" );
93
+ }
94
+
95
+ private void parseWhere (SQLExpr expr , Where where ) throws SqlParseException {
87
96
if (expr instanceof SQLBinaryOpExpr && !isCond ((SQLBinaryOpExpr ) expr )) {
88
97
SQLBinaryOpExpr bExpr = (SQLBinaryOpExpr ) expr ;
89
98
routeCond (bExpr , bExpr .getLeft (), where );
@@ -120,29 +129,48 @@ private void explanCond(String opear, SQLExpr expr, Where where) throws SqlParse
120
129
if (expr instanceof SQLBinaryOpExpr ) {
121
130
SQLBinaryOpExpr soExpr = (SQLBinaryOpExpr ) expr ;
122
131
boolean methodAsOpear = false ;
132
+ boolean nestedFieldCondition = false ;
133
+ String nestedPath = null ;
134
+ NestedType nestedType = new NestedType ();
135
+ if (tryFillNested (soExpr .getLeft (),nestedType )){
136
+ soExpr .setLeft (new SQLIdentifierExpr (nestedType .field ));
137
+ nestedFieldCondition = true ;
138
+ nestedPath = nestedType .path ;
139
+ }
140
+
123
141
if (soExpr .getRight () instanceof SQLMethodInvokeExpr ){
124
142
SQLMethodInvokeExpr method = (SQLMethodInvokeExpr ) soExpr .getRight ();
125
143
String methodName = method .getMethodName ().toLowerCase ();
126
144
127
145
if (Condition .OPEAR .methodNameToOpear .containsKey (methodName )){
128
146
Object [] methodParametersValue = getMethodValuesWithSubQueries (method );
129
- Condition condition = new Condition (CONN .valueOf (opear ) ,soExpr .getLeft ().toString (), Condition .OPEAR .methodNameToOpear .get (methodName ),methodParametersValue );
147
+ Condition condition = new Condition (CONN .valueOf (opear ) ,soExpr .getLeft ().toString (), Condition .OPEAR .methodNameToOpear .get (methodName ),methodParametersValue , nestedFieldCondition , nestedPath );
130
148
where .addWhere (condition );
131
149
methodAsOpear = true ;
132
150
}
133
151
}
134
152
if (!methodAsOpear ){
135
- Condition condition = new Condition (CONN .valueOf (opear ), soExpr .getLeft ().toString (), soExpr .getOperator ().name , parseValue (soExpr .getRight ()));
153
+ Condition condition = new Condition (CONN .valueOf (opear ), soExpr .getLeft ().toString (), soExpr .getOperator ().name , parseValue (soExpr .getRight ()), nestedFieldCondition , nestedPath );
136
154
where .addWhere (condition );
137
155
}
138
156
} else if (expr instanceof SQLInListExpr ) {
139
157
SQLInListExpr siExpr = (SQLInListExpr ) expr ;
140
- Condition condition = new Condition (CONN .valueOf (opear ), siExpr .getExpr ().toString (), siExpr .isNot () ? "NOT IN" : "IN" , parseValue (siExpr .getTargetList ()));
158
+ NestedType nestedType = new NestedType ();
159
+ String leftSide = siExpr .getExpr ().toString ();
160
+ if (tryFillNested (siExpr .getExpr (),nestedType )){
161
+ leftSide = nestedType .field ;
162
+ }
163
+ Condition condition = new Condition (CONN .valueOf (opear ), leftSide , siExpr .isNot () ? "NOT IN" : "IN" , parseValue (siExpr .getTargetList ()),nestedType .field !=null ,nestedType .path );
141
164
where .addWhere (condition );
142
165
} else if (expr instanceof SQLBetweenExpr ) {
143
166
SQLBetweenExpr between = ((SQLBetweenExpr ) expr );
144
- Condition condition = new Condition (CONN .valueOf (opear ), between .getTestExpr ().toString (), between .isNot () ? "NOT BETWEEN" : "BETWEEN" , new Object []{parseValue (between .beginExpr ),
145
- parseValue (between .endExpr )});
167
+ String leftSide = between .getTestExpr ().toString ();
168
+ NestedType nestedType = new NestedType ();
169
+ if (tryFillNested (between .getTestExpr (),nestedType )){
170
+ leftSide = nestedType .field ;
171
+ }
172
+ Condition condition = new Condition (CONN .valueOf (opear ), leftSide , between .isNot () ? "NOT BETWEEN" : "BETWEEN" , new Object []{parseValue (between .beginExpr ),
173
+ parseValue (between .endExpr )},nestedType .field !=null ,nestedType .path );
146
174
where .addWhere (condition );
147
175
}
148
176
else if (expr instanceof SQLMethodInvokeExpr ) {
@@ -151,23 +179,57 @@ else if (expr instanceof SQLMethodInvokeExpr) {
151
179
152
180
String methodName = methodExpr .getMethodName ();
153
181
String fieldName = methodParameters .get (0 ).toString ();
182
+ NestedType nestedType = new NestedType ();
183
+ if (tryFillNested (methodParameters .get (0 ),nestedType )){
184
+ fieldName = nestedType .field ;
185
+ }
186
+
154
187
Object spatialParamsObject = SpatialParamsFactory .generateSpatialParamsObject (methodName , methodParameters );
155
188
156
- Condition condition = new Condition (CONN .valueOf (opear ), fieldName , methodName , spatialParamsObject );
189
+ Condition condition = new Condition (CONN .valueOf (opear ), fieldName , methodName , spatialParamsObject , nestedType . field != null , nestedType . path );
157
190
where .addWhere (condition );
158
191
} else if (expr instanceof SQLInSubQueryExpr ){
159
192
SQLInSubQueryExpr sqlIn = (SQLInSubQueryExpr ) expr ;
160
193
Select innerSelect = parseSelect ((MySqlSelectQueryBlock ) sqlIn .getSubQuery ().getQuery ());
161
194
if (innerSelect .getFields () == null || innerSelect .getFields ().size ()!=1 )
162
195
throw new SqlParseException ("should only have one return field in subQuery" );
163
196
SubQueryExpression subQueryExpression = new SubQueryExpression (innerSelect );
164
- Condition condition = new Condition (CONN .valueOf (opear ), sqlIn .getExpr ().toString (), sqlIn .isNot () ? "NOT IN" : "IN" ,subQueryExpression );
197
+ String leftSide = sqlIn .getExpr ().toString ();
198
+ NestedType nestedType = new NestedType ();
199
+ if (tryFillNested (sqlIn .getExpr (),nestedType )){
200
+ leftSide = nestedType .field ;
201
+ }
202
+ Condition condition = new Condition (CONN .valueOf (opear ), leftSide , sqlIn .isNot () ? "NOT IN" : "IN" ,subQueryExpression ,nestedType .field !=null ,nestedType .path );
165
203
where .addWhere (condition );
166
204
} else {
167
205
throw new SqlParseException ("err find condition " + expr .getClass ());
168
206
}
169
207
}
170
208
209
+ private boolean tryFillNested (SQLExpr expr ,NestedType nestedType ) throws SqlParseException {
210
+ if (!(expr instanceof SQLMethodInvokeExpr )) return false ;
211
+ SQLMethodInvokeExpr method = (SQLMethodInvokeExpr ) expr ;
212
+ if (!method .getMethodName ().toLowerCase ().equals ("nested" )) return false ;
213
+
214
+ List <SQLExpr > parameters = method .getParameters ();
215
+ if (parameters .size () != 2 && parameters .size () != 1 )
216
+ throw new SqlParseException ("on nested object only allowed 2 parameters (field,path) or 1 parameter (field) " );
217
+
218
+ String field = parameters .get (0 ).toString ();
219
+ nestedType .field = field ;
220
+ if (parameters .size () == 1 ) {
221
+ //calc path myself..
222
+ if (!field .contains ("." ))
223
+ throw new SqlParseException ("nested should contain . on their field name" );
224
+ int lastDot = field .lastIndexOf ("." );
225
+ nestedType .path = field .substring (0 , lastDot );
226
+ } else if (parameters .size () == 2 ) {
227
+ nestedType .path = parameters .get (1 ).toString ();
228
+ }
229
+
230
+ return true ;
231
+ }
232
+
171
233
private Object [] getMethodValuesWithSubQueries (SQLMethodInvokeExpr method ) throws SqlParseException {
172
234
List <Object > values = new ArrayList <>();
173
235
boolean foundSubQuery = false ;
0 commit comments