in legacy/src/main/java/org/opensearch/sql/legacy/parser/WhereParser.java [223:502]
private void explainCond(String opear, SQLExpr expr, Where where) throws SqlParseException {
if (expr instanceof SQLBinaryOpExpr) {
SQLBinaryOpExpr soExpr = (SQLBinaryOpExpr) expr;
boolean methodAsOpear = false;
boolean isNested = false;
boolean isChildren = false;
NestedType nestedType = new NestedType();
if (nestedType.tryFillFromExpr(soExpr.getLeft())) {
soExpr.setLeft(new SQLIdentifierExpr(nestedType.field));
isNested = true;
}
ChildrenType childrenType = new ChildrenType();
if (childrenType.tryFillFromExpr(soExpr.getLeft())) {
soExpr.setLeft(new SQLIdentifierExpr(childrenType.field));
isChildren = true;
}
if (soExpr.getRight() instanceof SQLMethodInvokeExpr) {
SQLMethodInvokeExpr method = (SQLMethodInvokeExpr) soExpr.getRight();
String methodName = method.getMethodName().toLowerCase();
if (Condition.OPERATOR.methodNameToOpear.containsKey(methodName)) {
Object[] methodParametersValue = getMethodValuesWithSubQueries(method);
final Condition condition;
// fix OPEAR
Condition.OPERATOR oper = Condition.OPERATOR.methodNameToOpear.get(methodName);
if (soExpr.getOperator() == SQLBinaryOperator.LessThanOrGreater
|| soExpr.getOperator() == SQLBinaryOperator.NotEqual) {
oper = oper.negative();
}
if (isNested) {
condition = new Condition(Where.CONN.valueOf(opear), soExpr.getLeft().toString(),
soExpr.getLeft(), oper, methodParametersValue, soExpr.getRight(), nestedType);
} else if (isChildren) {
condition = new Condition(Where.CONN.valueOf(opear), soExpr.getLeft().toString(),
soExpr.getLeft(), oper, methodParametersValue, soExpr.getRight(), childrenType);
} else {
condition = new Condition(Where.CONN.valueOf(opear), soExpr.getLeft().toString(),
soExpr.getLeft(), oper, methodParametersValue, soExpr.getRight(), null);
}
where.addWhere(condition);
methodAsOpear = true;
}
}
if (!methodAsOpear) {
final Condition condition;
if (isNested) {
condition = new Condition(Where.CONN.valueOf(opear), soExpr.getLeft().toString(), soExpr.getLeft(),
soExpr.getOperator().name, parseValue(soExpr.getRight()), soExpr.getRight(), nestedType);
} else if (isChildren) {
condition = new Condition(Where.CONN.valueOf(opear), soExpr.getLeft().toString(), soExpr.getLeft(),
soExpr.getOperator().name, parseValue(soExpr.getRight()), soExpr.getRight(), childrenType);
} else {
SQLMethodInvokeExpr sqlMethodInvokeExpr = parseSQLBinaryOpExprWhoIsConditionInWhere(soExpr);
if (sqlMethodInvokeExpr == null) {
condition = new Condition(Where.CONN.valueOf(opear), soExpr.getLeft().toString(),
soExpr.getLeft(), soExpr.getOperator().name, parseValue(soExpr.getRight()),
soExpr.getRight(), null);
} else {
ScriptFilter scriptFilter = new ScriptFilter();
if (!scriptFilter.tryParseFromMethodExpr(sqlMethodInvokeExpr)) {
throw new SqlParseException("could not parse script filter");
}
condition = new Condition(Where.CONN.valueOf(opear), null, soExpr.getLeft(),
"SCRIPT", scriptFilter, soExpr.getRight());
}
}
where.addWhere(condition);
}
} else if (expr instanceof SQLInListExpr) {
SQLInListExpr siExpr = (SQLInListExpr) expr;
String leftSide = siExpr.getExpr().toString();
boolean isNested = false;
boolean isChildren = false;
NestedType nestedType = new NestedType();
if (nestedType.tryFillFromExpr(siExpr.getExpr())) {
leftSide = nestedType.field;
isNested = false;
}
ChildrenType childrenType = new ChildrenType();
if (childrenType.tryFillFromExpr(siExpr.getExpr())) {
leftSide = childrenType.field;
isChildren = true;
}
final Condition condition;
if (isNested) {
condition = new Condition(Where.CONN.valueOf(opear), leftSide, null, siExpr.isNot() ? "NOT IN" : "IN",
parseValue(siExpr.getTargetList()), null, nestedType);
} else if (isChildren) {
condition = new Condition(Where.CONN.valueOf(opear), leftSide, null, siExpr.isNot() ? "NOT IN" : "IN",
parseValue(siExpr.getTargetList()), null, childrenType);
} else {
condition = new Condition(Where.CONN.valueOf(opear), leftSide, null, siExpr.isNot() ? "NOT IN" : "IN",
parseValue(siExpr.getTargetList()), null);
}
where.addWhere(condition);
} else if (expr instanceof SQLBetweenExpr) {
SQLBetweenExpr between = ((SQLBetweenExpr) expr);
String leftSide = between.getTestExpr().toString();
boolean isNested = false;
boolean isChildren = false;
NestedType nestedType = new NestedType();
if (nestedType.tryFillFromExpr(between.getTestExpr())) {
leftSide = nestedType.field;
isNested = true;
}
ChildrenType childrenType = new ChildrenType();
if (childrenType.tryFillFromExpr(between.getTestExpr())) {
leftSide = childrenType.field;
isChildren = true;
}
final Condition condition;
if (isNested) {
condition = new Condition(Where.CONN.valueOf(opear), leftSide, null,
between.isNot() ? "NOT BETWEEN" : "BETWEEN", new Object[]{parseValue(between.beginExpr),
parseValue(between.endExpr)}, null, nestedType);
} else if (isChildren) {
condition = new Condition(Where.CONN.valueOf(opear), leftSide, null,
between.isNot() ? "NOT BETWEEN" : "BETWEEN", new Object[]{parseValue(between.beginExpr),
parseValue(between.endExpr)}, null, childrenType);
} else {
condition = new Condition(Where.CONN.valueOf(opear), leftSide, null,
between.isNot() ? "NOT BETWEEN" : "BETWEEN", new Object[]{parseValue(between.beginExpr),
parseValue(between.endExpr)}, null, null);
}
where.addWhere(condition);
} else if (expr instanceof SQLMethodInvokeExpr) {
SQLMethodInvokeExpr methodExpr = (SQLMethodInvokeExpr) expr;
List<SQLExpr> methodParameters = methodExpr.getParameters();
String methodName = methodExpr.getMethodName();
if (SpatialParamsFactory.isAllowedMethod(methodName)) {
String fieldName = methodParameters.get(0).toString();
boolean isNested = false;
boolean isChildren = false;
NestedType nestedType = new NestedType();
if (nestedType.tryFillFromExpr(methodParameters.get(0))) {
fieldName = nestedType.field;
isNested = true;
}
ChildrenType childrenType = new ChildrenType();
if (childrenType.tryFillFromExpr(methodParameters.get(0))) {
fieldName = childrenType.field;
isChildren = true;
}
Object spatialParamsObject = SpatialParamsFactory.generateSpatialParamsObject(methodName,
methodParameters);
final Condition condition;
if (isNested) {
condition = new Condition(Where.CONN.valueOf(opear), fieldName, null, methodName,
spatialParamsObject, null, nestedType);
} else if (isChildren) {
condition = new Condition(Where.CONN.valueOf(opear), fieldName, null, methodName,
spatialParamsObject, null, childrenType);
} else {
condition = new Condition(Where.CONN.valueOf(opear), fieldName, null, methodName,
spatialParamsObject, null, null);
}
where.addWhere(condition);
} else if (methodName.toLowerCase().equals("nested")) {
NestedType nestedType = new NestedType();
if (!nestedType.tryFillFromExpr(expr)) {
throw new SqlParseException("could not fill nested from expr:" + expr);
}
Condition condition = new Condition(Where.CONN.valueOf(opear), nestedType.path, null,
methodName.toUpperCase(), nestedType.where, null);
where.addWhere(condition);
} else if (methodName.toLowerCase().equals("children")) {
ChildrenType childrenType = new ChildrenType();
if (!childrenType.tryFillFromExpr(expr)) {
throw new SqlParseException("could not fill children from expr:" + expr);
}
Condition condition = new Condition(Where.CONN.valueOf(opear), childrenType.childType, null,
methodName.toUpperCase(), childrenType.where, null);
where.addWhere(condition);
} else if (methodName.toLowerCase().equals("script")) {
ScriptFilter scriptFilter = new ScriptFilter();
if (!scriptFilter.tryParseFromMethodExpr(methodExpr)) {
throw new SqlParseException("could not parse script filter");
}
Condition condition = new Condition(Where.CONN.valueOf(opear), null, null, "SCRIPT",
scriptFilter, null);
where.addWhere(condition);
} else if (Maker.isQueryFunction(methodName)) {
Condition condition = getConditionForMethod(expr, Where.CONN.valueOf(opear));
where.addWhere(condition);
} else {
throw new SqlParseException("unsupported method: " + methodName);
}
} else if (expr instanceof SQLInSubQueryExpr) {
SQLInSubQueryExpr sqlIn = (SQLInSubQueryExpr) expr;
Select innerSelect = sqlParser.parseSelect((MySqlSelectQueryBlock) sqlIn.getSubQuery().getQuery());
if (innerSelect.getFields() == null || innerSelect.getFields().size() != 1) {
throw new SqlParseException("should only have one return field in subQuery");
}
SubQueryExpression subQueryExpression = new SubQueryExpression(innerSelect);
String leftSide = sqlIn.getExpr().toString();
boolean isNested = false;
boolean isChildren = false;
NestedType nestedType = new NestedType();
if (nestedType.tryFillFromExpr(sqlIn.getExpr())) {
leftSide = nestedType.field;
isNested = true;
}
ChildrenType childrenType = new ChildrenType();
if (childrenType.tryFillFromExpr(sqlIn.getExpr())) {
leftSide = childrenType.field;
isChildren = true;
}
final Condition condition;
if (isNested) {
condition = new Condition(Where.CONN.valueOf(opear), leftSide, null, sqlIn.isNot() ? "NOT IN" : "IN",
subQueryExpression, null, nestedType);
} else if (isChildren) {
condition = new Condition(Where.CONN.valueOf(opear), leftSide, null, sqlIn.isNot() ? "NOT IN" : "IN",
subQueryExpression, null, childrenType);
} else {
condition = new Condition(Where.CONN.valueOf(opear), leftSide, null, sqlIn.isNot() ? "NOT IN" : "IN",
subQueryExpression, null, null);
}
where.addWhere(condition);
} else {
throw new SqlParseException("err find condition " + expr.getClass());
}
}