Skip to content

Commit

Permalink
Adding andrews fix for syntax option 2
Browse files Browse the repository at this point in the history
Signed-off-by: forestmvey <[email protected]>
  • Loading branch information
forestmvey committed May 5, 2023
1 parent c4b363f commit b187f62
Showing 1 changed file with 45 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@
import java.util.Map;
import java.util.function.BiFunction;
import lombok.RequiredArgsConstructor;
import org.apache.lucene.search.join.ScoreMode;
import org.opensearch.index.query.BoolQueryBuilder;
import org.opensearch.index.query.NestedQueryBuilder;
import org.opensearch.index.query.QueryBuilder;
import org.opensearch.index.query.QueryBuilders;
import org.opensearch.index.query.ScriptQueryBuilder;
Expand All @@ -23,6 +25,7 @@
import org.opensearch.sql.expression.Expression;
import org.opensearch.sql.expression.ExpressionNodeVisitor;
import org.opensearch.sql.expression.FunctionExpression;
import org.opensearch.sql.expression.ReferenceExpression;
import org.opensearch.sql.expression.function.BuiltinFunctionName;
import org.opensearch.sql.expression.function.FunctionName;
import org.opensearch.sql.opensearch.storage.script.filter.lucene.LikeQuery;
Expand Down Expand Up @@ -99,27 +102,57 @@ public QueryBuilder visitFunction(FunctionExpression func, Object context) {
return buildBoolQuery(func, context, BoolQueryBuilder::should);
case "not":
return buildBoolQuery(func, context, BoolQueryBuilder::mustNot);
case "nested":
// nested (field, condition)
// example: WHERE message.info = 'a' OR message.info = 'b'
// => bool { must { bool { should { term(message.info, 'a') , term(message.info, 'b') } } }

// example: WHERE nested(message.info) = 'a' OR nested(message.info) = 'b'
// => bool { must { bool { should { term( nested { term { message.info} } }, 'a') , term( nested { term { message.info} } }, 'b') } } }
// => bool { must { bool { nested { bool { must { term( message.info, 'a') , term( message.info, 'b') } } }

// example: WHERE nested(message.info, message.info = 'a' OR message.info = 'b' ...)
// => bool { must { bool { nested { bool { must { term( message.info, 'a') , term( message.info, 'b') } } }

// => bool { must { nested { bool { should { term() , term() } } } }
// example: WHERE nested(message.info, message.age > 20 OR message.info = 'b' ...)
// example: WHERE nested(message.info.name, message.info.name = 'a') OR nested(message.info.address, message.info.address = 'b')

// WHERE nested(message, message.info.name, message.info.name = "Andrew" OR message.comment = "SECOND")
// WHERE (nested(message.info.name) = "Andrew" AND nested(message.comment) = "FIRST") OR (nested(message.info.name) = "Guian" AND nested(message.comment = "SECOND"))

// example: WHERE nested(foo.bar, nested(zoo.blah, condition))

if (func.getArguments().size() > 1) {
Expression secondArgument = func.getArguments().get(1);
if (secondArgument instanceof FunctionExpression) {
ReferenceExpression field = (ReferenceExpression)func.getArguments().get(0);
FunctionExpression condition = (FunctionExpression)func.getArguments().get(1);
QueryBuilder queryBuilder = visitFunction(condition, context);
NestedQueryBuilder
nestedQueryBuilder = QueryBuilders.nestedQuery(getNestedPathString(field), queryBuilder, ScoreMode.None);
return nestedQueryBuilder;
}
}
// else, this doesn't have a condition so we need to just call nested without a queryBuilder
default: {
LuceneQuery query = luceneQueries.get(name);
// Nested used in predicate expression with syntax 'WHERE nested(field | field, path) = ...'
if (func.getArguments().get(0) instanceof FunctionExpression
&& ((FunctionExpression)func.getArguments().get(0)).getFunctionName().getFunctionName().equalsIgnoreCase(BuiltinFunctionName.NESTED.name())) {
LuceneQuery innerQuery = luceneQueries.get(((FunctionExpression)func.getArguments().get(0)).getFunctionName());
return innerQuery.build(func);
// containsInnerNestedQuery()
// innerQuery.buildPredicateExpression()
} else if (query instanceof NestedQuery) {
// TODO Throw exception if does not have conditional parameter.
return query.build(func);
}
if (query != null && query.canSupport(func)) {
if (query != null && query.canSupport(func)) {
return query.build(func);
}
return buildScriptQuery(func);
}
}
}

private String getNestedPathString(ReferenceExpression field) {
String ret = "";
for (int i = 0; i < field.getPaths().size() - 1; i++) {
ret += (i == 0) ? field.getPaths().get(i) : "." + field.getPaths().get(i);
}
return ret;
}

private BoolQueryBuilder buildBoolQuery(FunctionExpression node,
Object context,
BiFunction<BoolQueryBuilder, QueryBuilder,
Expand Down

0 comments on commit b187f62

Please sign in to comment.