diff --git a/build.gradle b/build.gradle index f623b5da4e..c5d771c8b3 100644 --- a/build.gradle +++ b/build.gradle @@ -85,7 +85,8 @@ spotless { java { target fileTree('.') { include 'datasources/**/*.java', - 'core/**/*.java' + 'core/**/*.java', + 'sql/**/*.java' exclude '**/build/**', '**/build-*/**' } importOrder() diff --git a/sql/build.gradle b/sql/build.gradle index 44dc37cf0f..d85cc4ca74 100644 --- a/sql/build.gradle +++ b/sql/build.gradle @@ -58,6 +58,11 @@ dependencies { testImplementation(testFixtures(project(":core"))) } +// Being ignored as a temporary measure before being removed in favour of +// spotless https://github.com/opensearch-project/sql/issues/1101 +checkstyleTest.ignoreFailures = true +checkstyleMain.ignoreFailures = true + test { useJUnitPlatform() testLogging { diff --git a/sql/src/main/java/org/opensearch/sql/sql/SQLService.java b/sql/src/main/java/org/opensearch/sql/sql/SQLService.java index 91ec00cdd5..e1ca778453 100644 --- a/sql/src/main/java/org/opensearch/sql/sql/SQLService.java +++ b/sql/src/main/java/org/opensearch/sql/sql/SQLService.java @@ -3,7 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ - package org.opensearch.sql.sql; import java.util.Optional; @@ -21,9 +20,7 @@ import org.opensearch.sql.sql.parser.AstBuilder; import org.opensearch.sql.sql.parser.AstStatementBuilder; -/** - * SQL service. - */ +/** SQL service. */ @RequiredArgsConstructor public class SQLService { @@ -69,15 +66,19 @@ private AbstractPlan plan( if (request.getCursor().isPresent()) { // Handle v2 cursor here -- legacy cursor was handled earlier. if (isExplainRequest) { - throw new UnsupportedOperationException("Explain of a paged query continuation " - + "is not supported. Use `explain` for the initial query request."); + throw new UnsupportedOperationException( + "Explain of a paged query continuation " + + "is not supported. Use `explain` for the initial query request."); } if (request.isCursorCloseRequest()) { - return queryExecutionFactory.createCloseCursor(request.getCursor().get(), - queryListener.orElse(null)); + return queryExecutionFactory.createCloseCursor( + request.getCursor().get(), queryListener.orElse(null)); } - return queryExecutionFactory.create(request.getCursor().get(), - isExplainRequest, queryListener.orElse(null), explainListener.orElse(null)); + return queryExecutionFactory.create( + request.getCursor().get(), + isExplainRequest, + queryListener.orElse(null), + explainListener.orElse(null)); } else { // 1.Parse query and convert parse tree (CST) to abstract syntax tree (AST) ParseTree cst = parser.parse(request.getQuery()); @@ -90,8 +91,7 @@ private AbstractPlan plan( .fetchSize(request.getFetchSize()) .build())); - return queryExecutionFactory.create( - statement, queryListener, explainListener); + return queryExecutionFactory.create(statement, queryListener, explainListener); } } } diff --git a/sql/src/main/java/org/opensearch/sql/sql/antlr/AnonymizerListener.java b/sql/src/main/java/org/opensearch/sql/sql/antlr/AnonymizerListener.java index bd7b5cbedf..0d1b89f7a9 100644 --- a/sql/src/main/java/org/opensearch/sql/sql/antlr/AnonymizerListener.java +++ b/sql/src/main/java/org/opensearch/sql/sql/antlr/AnonymizerListener.java @@ -3,7 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ - package org.opensearch.sql.sql.antlr; import static org.opensearch.sql.sql.antlr.parser.OpenSearchSQLLexer.BACKTICK_QUOTE_ID; @@ -31,21 +30,17 @@ import org.antlr.v4.runtime.tree.ParseTreeListener; import org.antlr.v4.runtime.tree.TerminalNode; -/** - * Parse tree listener for anonymizing SQL requests. - */ +/** Parse tree listener for anonymizing SQL requests. */ public class AnonymizerListener implements ParseTreeListener { private String anonymizedQueryString = ""; private static final int NO_TYPE = -1; private int previousType = NO_TYPE; @Override - public void enterEveryRule(ParserRuleContext ctx) { - } + public void enterEveryRule(ParserRuleContext ctx) {} @Override - public void exitEveryRule(ParserRuleContext ctx) { - } + public void exitEveryRule(ParserRuleContext ctx) {} @Override public void visitTerminal(TerminalNode node) { @@ -57,10 +52,11 @@ public void visitTerminal(TerminalNode node) { int token = node.getSymbol().getType(); boolean isDotIdentifiers = token == DOT || previousType == DOT; boolean isComma = token == COMMA; - boolean isEqualComparison = ((token == EQUAL_SYMBOL) + boolean isEqualComparison = + ((token == EQUAL_SYMBOL) && (previousType == LESS_SYMBOL - || previousType == GREATER_SYMBOL - || previousType == EXCLAMATION_SYMBOL)); + || previousType == GREATER_SYMBOL + || previousType == EXCLAMATION_SYMBOL)); boolean isNotEqualComparisonAlternative = previousType == LESS_SYMBOL && token == GREATER_SYMBOL; if (!isDotIdentifiers && !isComma && !isEqualComparison && !isNotEqualComparisonAlternative) { @@ -103,9 +99,7 @@ public void visitTerminal(TerminalNode node) { } @Override - public void visitErrorNode(ErrorNode node) { - - } + public void visitErrorNode(ErrorNode node) {} public String getAnonymizedQueryString() { return "(" + anonymizedQueryString + ")"; diff --git a/sql/src/main/java/org/opensearch/sql/sql/antlr/SQLSyntaxParser.java b/sql/src/main/java/org/opensearch/sql/sql/antlr/SQLSyntaxParser.java index 4f7b925718..d1a6adc236 100644 --- a/sql/src/main/java/org/opensearch/sql/sql/antlr/SQLSyntaxParser.java +++ b/sql/src/main/java/org/opensearch/sql/sql/antlr/SQLSyntaxParser.java @@ -3,7 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ - package org.opensearch.sql.sql.antlr; import org.antlr.v4.runtime.CommonTokenStream; @@ -16,16 +15,15 @@ import org.opensearch.sql.sql.antlr.parser.OpenSearchSQLLexer; import org.opensearch.sql.sql.antlr.parser.OpenSearchSQLParser; -/** - * SQL syntax parser which encapsulates an ANTLR parser. - */ +/** SQL syntax parser which encapsulates an ANTLR parser. */ public class SQLSyntaxParser implements Parser { private static final Logger LOG = LogManager.getLogger(SQLSyntaxParser.class); /** * Parse a SQL query by ANTLR parser. - * @param query a SQL query - * @return parse tree root + * + * @param query a SQL query + * @return parse tree root */ @Override public ParseTree parse(String query) { diff --git a/sql/src/main/java/org/opensearch/sql/sql/domain/SQLQueryRequest.java b/sql/src/main/java/org/opensearch/sql/sql/domain/SQLQueryRequest.java index c9321f5775..4e902cb67d 100644 --- a/sql/src/main/java/org/opensearch/sql/sql/domain/SQLQueryRequest.java +++ b/sql/src/main/java/org/opensearch/sql/sql/domain/SQLQueryRequest.java @@ -3,7 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ - package org.opensearch.sql.sql.domain; import java.util.Collections; @@ -20,43 +19,30 @@ import org.json.JSONObject; import org.opensearch.sql.protocol.response.format.Format; -/** - * SQL query request. - */ +/** SQL query request. */ @ToString @EqualsAndHashCode @RequiredArgsConstructor public class SQLQueryRequest { private static final String QUERY_FIELD_CURSOR = "cursor"; - private static final Set SUPPORTED_FIELDS = Set.of( - "query", "fetch_size", "parameters", QUERY_FIELD_CURSOR); + private static final Set SUPPORTED_FIELDS = + Set.of("query", "fetch_size", "parameters", QUERY_FIELD_CURSOR); private static final String QUERY_PARAMS_FORMAT = "format"; private static final String QUERY_PARAMS_SANITIZE = "sanitize"; - /** - * JSON payload in REST request. - */ + /** JSON payload in REST request. */ private final JSONObject jsonContent; - /** - * SQL query. - */ - @Getter - private final String query; + /** SQL query. */ + @Getter private final String query; - /** - * Request path. - */ + /** Request path. */ private final String path; - /** - * Request format. - */ + /** Request format. */ private final String format; - /** - * Request params. - */ + /** Request params. */ private Map params = Collections.emptyMap(); @Getter @@ -65,11 +51,13 @@ public class SQLQueryRequest { private String cursor; - /** - * Constructor of SQLQueryRequest that passes request params. - */ - public SQLQueryRequest(JSONObject jsonContent, String query, String path, - Map params, String cursor) { + /** Constructor of SQLQueryRequest that passes request params. */ + public SQLQueryRequest( + JSONObject jsonContent, + String query, + String path, + Map params, + String cursor) { this.jsonContent = jsonContent; this.query = query; this.path = path; @@ -80,24 +68,30 @@ public SQLQueryRequest(JSONObject jsonContent, String query, String path, } /** + * + * + *
    * Pre-check if the request can be supported by meeting ALL the following criteria:
    *  1.Only supported fields present in request body, ex. "filter" and "cursor" are not supported
    *  2.Response format is default or can be supported.
+   * 
* * @return true if supported. */ public boolean isSupported() { var noCursor = !isCursor(); var noQuery = query == null; - var noUnsupportedParams = params.isEmpty() - || (params.size() == 1 && params.containsKey(QUERY_PARAMS_FORMAT)); + var noUnsupportedParams = + params.isEmpty() || (params.size() == 1 && params.containsKey(QUERY_PARAMS_FORMAT)); var noContent = jsonContent == null || jsonContent.isEmpty(); - return ((!noCursor && noQuery - && noUnsupportedParams && noContent) // if cursor is given, but other things - || (noCursor && !noQuery)) // or if cursor is not given, but query - && isOnlySupportedFieldInPayload() // and request has supported fields only - && isSupportedFormat(); // and request is in supported format + return ((!noCursor + && noQuery + && noUnsupportedParams + && noContent) // if cursor is given, but other things + || (noCursor && !noQuery)) // or if cursor is not given, but query + && isOnlySupportedFieldInPayload() // and request has supported fields only + && isSupportedFormat(); // and request is in supported format } private boolean isCursor() { @@ -106,6 +100,7 @@ private boolean isCursor() { /** * Check if request is to explain rather than execute the query. + * * @return true if it is an explain request */ public boolean isExplainRequest() { @@ -116,16 +111,14 @@ public boolean isCursorCloseRequest() { return path.endsWith("/close"); } - /** - * Decide on the formatter by the requested format. - */ + /** Decide on the formatter by the requested format. */ public Format format() { Optional optionalFormat = Format.of(format); if (optionalFormat.isPresent()) { return optionalFormat.get(); } else { throw new IllegalArgumentException( - String.format(Locale.ROOT,"response in %s format is not supported.", format)); + String.format(Locale.ROOT, "response in %s format is not supported.", format)); } } @@ -155,5 +148,4 @@ private boolean shouldSanitize(Map params) { } return true; } - } diff --git a/sql/src/main/java/org/opensearch/sql/sql/parser/AstAggregationBuilder.java b/sql/src/main/java/org/opensearch/sql/sql/parser/AstAggregationBuilder.java index bd4464d00e..e46147b7a3 100644 --- a/sql/src/main/java/org/opensearch/sql/sql/parser/AstAggregationBuilder.java +++ b/sql/src/main/java/org/opensearch/sql/sql/parser/AstAggregationBuilder.java @@ -3,7 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ - package org.opensearch.sql.sql.parser; import static java.util.Collections.emptyList; @@ -27,6 +26,8 @@ import org.opensearch.sql.sql.parser.context.QuerySpecification; /** + * + * *
SelectExpressionAnalyzerTest
  * AST aggregation builder that builds AST aggregation node for the following scenarios:
  *
@@ -59,9 +60,7 @@
 @RequiredArgsConstructor
 public class AstAggregationBuilder extends OpenSearchSQLParserBaseVisitor {
 
-  /**
-   * Query specification that contains info collected beforehand.
-   */
+  /** Query specification that contains info collected beforehand. */
   private final QuerySpecification querySpec;
 
   @Override
@@ -78,10 +77,7 @@ public UnresolvedPlan visit(ParseTree groupByClause) {
 
   private UnresolvedPlan buildExplicitAggregation() {
     List groupByItems = replaceGroupByItemIfAliasOrOrdinal();
-    return new Aggregation(
-        new ArrayList<>(querySpec.getAggregators()),
-        emptyList(),
-        groupByItems);
+    return new Aggregation(new ArrayList<>(querySpec.getAggregators()), emptyList(), groupByItems);
   }
 
   private UnresolvedPlan buildImplicitAggregation() {
@@ -89,33 +85,32 @@ private UnresolvedPlan buildImplicitAggregation() {
 
     if (invalidSelectItem.isPresent()) {
       // Report semantic error to avoid fall back to old engine again
-      throw new SemanticCheckException(StringUtils.format(
-          "Explicit GROUP BY clause is required because expression [%s] "
-              + "contains non-aggregated column", invalidSelectItem.get()));
+      throw new SemanticCheckException(
+          StringUtils.format(
+              "Explicit GROUP BY clause is required because expression [%s] "
+                  + "contains non-aggregated column",
+              invalidSelectItem.get()));
     }
 
     return new Aggregation(
-        new ArrayList<>(querySpec.getAggregators()),
-        emptyList(),
-        querySpec.getGroupByItems());
+        new ArrayList<>(querySpec.getAggregators()), emptyList(), querySpec.getGroupByItems());
   }
 
   private List replaceGroupByItemIfAliasOrOrdinal() {
-    return querySpec.getGroupByItems()
-                    .stream()
-                    .map(querySpec::replaceIfAliasOrOrdinal)
-                    .map(expr -> new Alias(expr.toString(), expr))
-                    .collect(Collectors.toList());
+    return querySpec.getGroupByItems().stream()
+        .map(querySpec::replaceIfAliasOrOrdinal)
+        .map(expr -> new Alias(expr.toString(), expr))
+        .collect(Collectors.toList());
   }
 
   /**
-   * Find non-aggregate item in SELECT clause. Note that literal is special which is not required
-   * to be applied by aggregate function.
+   * Find non-aggregate item in SELECT clause. Note that literal is special which is not required to
+   * be applied by aggregate function.
    */
   private Optional findNonAggregatedItemInSelect() {
     return querySpec.getSelectItems().stream()
-                                     .filter(this::isNonAggregateOrLiteralExpression)
-                                     .findFirst();
+        .filter(this::isNonAggregateOrLiteralExpression)
+        .findFirst();
   }
 
   private boolean isAggregatorNotFoundAnywhere() {
@@ -132,8 +127,7 @@ private boolean isNonAggregateOrLiteralExpression(UnresolvedExpression expr) {
     }
 
     List children = expr.getChild();
-    return children.stream().anyMatch(child ->
-        isNonAggregateOrLiteralExpression((UnresolvedExpression) child));
+    return children.stream()
+        .anyMatch(child -> isNonAggregateOrLiteralExpression((UnresolvedExpression) child));
   }
-
 }
diff --git a/sql/src/main/java/org/opensearch/sql/sql/parser/AstBuilder.java b/sql/src/main/java/org/opensearch/sql/sql/parser/AstBuilder.java
index 020889c082..ab96f16263 100644
--- a/sql/src/main/java/org/opensearch/sql/sql/parser/AstBuilder.java
+++ b/sql/src/main/java/org/opensearch/sql/sql/parser/AstBuilder.java
@@ -3,7 +3,6 @@
  * SPDX-License-Identifier: Apache-2.0
  */
 
-
 package org.opensearch.sql.sql.parser;
 
 import static java.util.Collections.emptyList;
@@ -43,22 +42,18 @@
 import org.opensearch.sql.sql.antlr.parser.OpenSearchSQLParserBaseVisitor;
 import org.opensearch.sql.sql.parser.context.ParsingContext;
 
-/**
- * Abstract syntax tree (AST) builder.
- */
+/** Abstract syntax tree (AST) builder. */
 @RequiredArgsConstructor
 public class AstBuilder extends OpenSearchSQLParserBaseVisitor {
 
   private final AstExpressionBuilder expressionBuilder = new AstExpressionBuilder();
 
-  /**
-   * Parsing context stack that contains context for current query parsing.
-   */
+  /** Parsing context stack that contains context for current query parsing. */
   private final ParsingContext context = new ParsingContext();
 
   /**
-   * SQL query to get original token text. This is necessary because token.getText() returns
-   * text without whitespaces or other characters discarded by lexer.
+   * SQL query to get original token text. This is necessary because token.getText() returns text
+   * without whitespaces or other characters discarded by lexer.
    */
   private final String query;
 
@@ -91,8 +86,7 @@ public UnresolvedPlan visitQuerySpecification(QuerySpecificationContext queryCon
 
     if (queryContext.fromClause() == null) {
       Optional allFields =
-          project.getProjectList().stream().filter(node -> node instanceof AllFields)
-              .findFirst();
+          project.getProjectList().stream().filter(node -> node instanceof AllFields).findFirst();
       if (allFields.isPresent()) {
         throw new SyntaxCheckException("No FROM clause found for select all");
       }
@@ -119,9 +113,8 @@ public UnresolvedPlan visitQuerySpecification(QuerySpecificationContext queryCon
 
   @Override
   public UnresolvedPlan visitSelectClause(SelectClauseContext ctx) {
-    ImmutableList.Builder builder =
-        new ImmutableList.Builder<>();
-    if (ctx.selectElements().star != null) { //TODO: project operator should be required?
+    ImmutableList.Builder builder = new ImmutableList.Builder<>();
+    if (ctx.selectElements().star != null) { // TODO: project operator should be required?
       builder.add(AllFields.of());
     }
     ctx.selectElements().selectElement().forEach(field -> builder.add(visitSelectItem(field)));
@@ -132,8 +125,7 @@ public UnresolvedPlan visitSelectClause(SelectClauseContext ctx) {
   public UnresolvedPlan visitLimitClause(OpenSearchSQLParser.LimitClauseContext ctx) {
     return new Limit(
         Integer.parseInt(ctx.limit.getText()),
-        ctx.offset == null ? 0 : Integer.parseInt(ctx.offset.getText())
-    );
+        ctx.offset == null ? 0 : Integer.parseInt(ctx.offset.getText()));
   }
 
   @Override
@@ -165,29 +157,26 @@ public UnresolvedPlan visitFromClause(FromClauseContext ctx) {
   }
 
   /**
-   * Ensure NESTED function is not used in HAVING clause and fallback to legacy engine.
-   * Can remove when support is added for NESTED function in HAVING clause.
+   * Ensure NESTED function is not used in HAVING clause and fallback to legacy engine. Can remove
+   * when support is added for NESTED function in HAVING clause.
+   *
    * @param func : Function in HAVING clause
    */
   private void verifySupportsCondition(UnresolvedExpression func) {
     if (func instanceof Function) {
-      if (((Function) func).getFuncName().equalsIgnoreCase(
-          BuiltinFunctionName.NESTED.name()
-      )) {
+      if (((Function) func).getFuncName().equalsIgnoreCase(BuiltinFunctionName.NESTED.name())) {
         throw new SyntaxCheckException(
-            "Falling back to legacy engine. Nested function is not supported in the HAVING clause."
-        );
+            "Falling back to legacy engine. Nested function is not supported in the HAVING"
+                + " clause.");
       }
-      ((Function)func).getFuncArgs().stream()
-          .forEach(e -> verifySupportsCondition(e)
-      );
+      ((Function) func).getFuncArgs().stream().forEach(e -> verifySupportsCondition(e));
     }
   }
 
   @Override
   public UnresolvedPlan visitTableAsRelation(TableAsRelationContext ctx) {
-    String tableAlias = (ctx.alias() == null) ? null
-        : StringUtils.unquoteIdentifier(ctx.alias().getText());
+    String tableAlias =
+        (ctx.alias() == null) ? null : StringUtils.unquoteIdentifier(ctx.alias().getText());
     return new Relation(visitAstExpression(ctx.tableName()), tableAlias);
   }
 
@@ -228,5 +217,4 @@ private UnresolvedExpression visitSelectItem(SelectElementContext ctx) {
       return new Alias(name, expr, alias);
     }
   }
-
 }
diff --git a/sql/src/main/java/org/opensearch/sql/sql/parser/AstExpressionBuilder.java b/sql/src/main/java/org/opensearch/sql/sql/parser/AstExpressionBuilder.java
index 192514250b..6dd1e02a1d 100644
--- a/sql/src/main/java/org/opensearch/sql/sql/parser/AstExpressionBuilder.java
+++ b/sql/src/main/java/org/opensearch/sql/sql/parser/AstExpressionBuilder.java
@@ -3,7 +3,6 @@
  * SPDX-License-Identifier: Apache-2.0
  */
 
-
 package org.opensearch.sql.sql.parser;
 
 import static org.opensearch.sql.ast.dsl.AstDSL.between;
@@ -113,9 +112,7 @@
 import org.opensearch.sql.sql.antlr.parser.OpenSearchSQLParser.TableNameContext;
 import org.opensearch.sql.sql.antlr.parser.OpenSearchSQLParserBaseVisitor;
 
-/**
- * Expression builder to parse text to expression in AST.
- */
+/** Expression builder to parse text to expression in AST. */
 public class AstExpressionBuilder extends OpenSearchSQLParserBaseVisitor {
 
   @Override
@@ -141,9 +138,7 @@ public UnresolvedExpression visitQualifiedName(QualifiedNameContext ctx) {
   @Override
   public UnresolvedExpression visitMathExpressionAtom(MathExpressionAtomContext ctx) {
     return new Function(
-        ctx.mathOperator.getText(),
-        Arrays.asList(visit(ctx.left), visit(ctx.right))
-    );
+        ctx.mathOperator.getText(), Arrays.asList(visit(ctx.left), visit(ctx.right)));
   }
 
   @Override
@@ -152,11 +147,8 @@ public UnresolvedExpression visitNestedExpressionAtom(NestedExpressionAtomContex
   }
 
   @Override
-  public UnresolvedExpression visitNestedAllFunctionCall(
-      NestedAllFunctionCallContext ctx) {
-    return new NestedAllTupleFields(
-        visitQualifiedName(ctx.allTupleFields().path).toString()
-    );
+  public UnresolvedExpression visitNestedAllFunctionCall(NestedAllFunctionCallContext ctx) {
+    return new NestedAllTupleFields(visitQualifiedName(ctx.allTupleFields().path).toString());
   }
 
   @Override
@@ -167,39 +159,36 @@ public UnresolvedExpression visitScalarFunctionCall(ScalarFunctionCallContext ct
   @Override
   public UnresolvedExpression visitGetFormatFunctionCall(GetFormatFunctionCallContext ctx) {
     return new Function(
-        ctx.getFormatFunction().GET_FORMAT().toString(),
-        getFormatFunctionArguments(ctx));
+        ctx.getFormatFunction().GET_FORMAT().toString(), getFormatFunctionArguments(ctx));
   }
 
   @Override
-  public UnresolvedExpression visitHighlightFunctionCall(
-      HighlightFunctionCallContext ctx) {
+  public UnresolvedExpression visitHighlightFunctionCall(HighlightFunctionCallContext ctx) {
     ImmutableMap.Builder builder = ImmutableMap.builder();
-    ctx.highlightFunction().highlightArg().forEach(v -> builder.put(
-        v.highlightArgName().getText().toLowerCase(),
-        new Literal(StringUtils.unquoteText(v.highlightArgValue().getText()),
-            DataType.STRING))
-    );
+    ctx.highlightFunction()
+        .highlightArg()
+        .forEach(
+            v ->
+                builder.put(
+                    v.highlightArgName().getText().toLowerCase(),
+                    new Literal(
+                        StringUtils.unquoteText(v.highlightArgValue().getText()),
+                        DataType.STRING)));
 
-    return new HighlightFunction(visit(ctx.highlightFunction().relevanceField()),
-        builder.build());
+    return new HighlightFunction(visit(ctx.highlightFunction().relevanceField()), builder.build());
   }
 
-
   @Override
   public UnresolvedExpression visitTimestampFunctionCall(TimestampFunctionCallContext ctx) {
     return new Function(
-        ctx.timestampFunction().timestampFunctionName().getText(),
-        timestampFunctionArguments(ctx));
+        ctx.timestampFunction().timestampFunctionName().getText(), timestampFunctionArguments(ctx));
   }
 
   @Override
-  public UnresolvedExpression visitPositionFunction(
-          PositionFunctionContext ctx) {
+  public UnresolvedExpression visitPositionFunction(PositionFunctionContext ctx) {
     return new Function(
-            POSITION.getName().getFunctionName(),
-            Arrays.asList(visitFunctionArg(ctx.functionArg(0)),
-                visitFunctionArg(ctx.functionArg(1))));
+        POSITION.getName().getFunctionName(),
+        Arrays.asList(visitFunctionArg(ctx.functionArg(0)), visitFunctionArg(ctx.functionArg(1))));
   }
 
   @Override
@@ -217,8 +206,7 @@ public UnresolvedExpression visitColumnFilter(ColumnFilterContext ctx) {
   }
 
   @Override
-  public UnresolvedExpression visitShowDescribePattern(
-      ShowDescribePatternContext ctx) {
+  public UnresolvedExpression visitShowDescribePattern(ShowDescribePatternContext ctx) {
     return visit(ctx.stringLiteral());
   }
 
@@ -235,21 +223,18 @@ public UnresolvedExpression visitWindowFunctionClause(WindowFunctionClauseContex
 
     List partitionByList = Collections.emptyList();
     if (overClause.partitionByClause() != null) {
-      partitionByList = overClause.partitionByClause()
-                                  .expression()
-                                  .stream()
-                                  .map(this::visit)
-                                  .collect(Collectors.toList());
+      partitionByList =
+          overClause.partitionByClause().expression().stream()
+              .map(this::visit)
+              .collect(Collectors.toList());
     }
 
     List> sortList = Collections.emptyList();
     if (overClause.orderByClause() != null) {
-      sortList = overClause.orderByClause()
-                           .orderByElement()
-                           .stream()
-                           .map(item -> ImmutablePair.of(
-                               createSortOption(item), visit(item.expression())))
-                           .collect(Collectors.toList());
+      sortList =
+          overClause.orderByClause().orderByElement().stream()
+              .map(item -> ImmutablePair.of(createSortOption(item), visit(item.expression())))
+              .collect(Collectors.toList());
     }
     return new WindowFunction(visit(ctx.function), partitionByList, sortList);
   }
@@ -262,17 +247,12 @@ public UnresolvedExpression visitScalarWindowFunction(ScalarWindowFunctionContex
   @Override
   public UnresolvedExpression visitRegularAggregateFunctionCall(
       RegularAggregateFunctionCallContext ctx) {
-    return new AggregateFunction(
-        ctx.functionName.getText(),
-        visitFunctionArg(ctx.functionArg()));
+    return new AggregateFunction(ctx.functionName.getText(), visitFunctionArg(ctx.functionArg()));
   }
 
   @Override
   public UnresolvedExpression visitDistinctCountFunctionCall(DistinctCountFunctionCallContext ctx) {
-    return new AggregateFunction(
-        ctx.COUNT().getText(),
-        visitFunctionArg(ctx.functionArg()),
-        true);
+    return new AggregateFunction(ctx.COUNT().getText(), visitFunctionArg(ctx.functionArg()), true);
   }
 
   @Override
@@ -288,18 +268,16 @@ public UnresolvedExpression visitFilterClause(FilterClauseContext ctx) {
   @Override
   public UnresolvedExpression visitIsNullPredicate(IsNullPredicateContext ctx) {
     return new Function(
-        ctx.nullNotnull().NOT() == null ? IS_NULL.getName().getFunctionName() :
-            IS_NOT_NULL.getName().getFunctionName(),
+        ctx.nullNotnull().NOT() == null
+            ? IS_NULL.getName().getFunctionName()
+            : IS_NOT_NULL.getName().getFunctionName(),
         Arrays.asList(visit(ctx.predicate())));
   }
 
   @Override
   public UnresolvedExpression visitBetweenPredicate(BetweenPredicateContext ctx) {
     UnresolvedExpression func =
-        between(
-            visit(ctx.predicate(0)),
-            visit(ctx.predicate(1)),
-            visit(ctx.predicate(2)));
+        between(visit(ctx.predicate(0)), visit(ctx.predicate(1)), visit(ctx.predicate(2)));
 
     if (ctx.NOT() != null) {
       func = not(func);
@@ -310,26 +288,21 @@ public UnresolvedExpression visitBetweenPredicate(BetweenPredicateContext ctx) {
   @Override
   public UnresolvedExpression visitLikePredicate(LikePredicateContext ctx) {
     return new Function(
-        ctx.NOT() == null ? LIKE.getName().getFunctionName() :
-            NOT_LIKE.getName().getFunctionName(),
+        ctx.NOT() == null ? LIKE.getName().getFunctionName() : NOT_LIKE.getName().getFunctionName(),
         Arrays.asList(visit(ctx.left), visit(ctx.right)));
   }
 
   @Override
   public UnresolvedExpression visitRegexpPredicate(RegexpPredicateContext ctx) {
-    return new Function(REGEXP.getName().getFunctionName(),
-            Arrays.asList(visit(ctx.left), visit(ctx.right)));
+    return new Function(
+        REGEXP.getName().getFunctionName(), Arrays.asList(visit(ctx.left), visit(ctx.right)));
   }
 
   @Override
   public UnresolvedExpression visitInPredicate(InPredicateContext ctx) {
     UnresolvedExpression field = visit(ctx.predicate());
-    List inLists = ctx
-        .expressions()
-        .expression()
-        .stream()
-        .map(this::visit)
-        .collect(Collectors.toList());
+    List inLists =
+        ctx.expressions().expression().stream().map(this::visit).collect(Collectors.toList());
     UnresolvedExpression in = AstDSL.in(field, inLists);
     return ctx.NOT() != null ? AstDSL.not(in) : in;
   }
@@ -394,34 +367,30 @@ public UnresolvedExpression visitTimeLiteral(TimeLiteralContext ctx) {
   }
 
   @Override
-  public UnresolvedExpression visitTimestampLiteral(
-      TimestampLiteralContext ctx) {
+  public UnresolvedExpression visitTimestampLiteral(TimestampLiteralContext ctx) {
     return AstDSL.timestampLiteral(StringUtils.unquoteText(ctx.timestamp.getText()));
   }
 
   @Override
   public UnresolvedExpression visitIntervalLiteral(IntervalLiteralContext ctx) {
-    return new Interval(
-        visit(ctx.expression()), IntervalUnit.of(ctx.intervalUnit().getText()));
+    return new Interval(visit(ctx.expression()), IntervalUnit.of(ctx.intervalUnit().getText()));
   }
 
   @Override
-  public UnresolvedExpression visitBinaryComparisonPredicate(
-      BinaryComparisonPredicateContext ctx) {
+  public UnresolvedExpression visitBinaryComparisonPredicate(BinaryComparisonPredicateContext ctx) {
     String functionName = ctx.comparisonOperator().getText();
     return new Function(
         functionName.equals("<>") ? "!=" : functionName,
-        Arrays.asList(visit(ctx.left), visit(ctx.right))
-    );
+        Arrays.asList(visit(ctx.left), visit(ctx.right)));
   }
 
   @Override
   public UnresolvedExpression visitCaseFunctionCall(CaseFunctionCallContext ctx) {
     UnresolvedExpression caseValue = (ctx.expression() == null) ? null : visit(ctx.expression());
-    List whenStatements = ctx.caseFuncAlternative()
-                                   .stream()
-                                   .map(when -> (When) visit(when))
-                                   .collect(Collectors.toList());
+    List whenStatements =
+        ctx.caseFuncAlternative().stream()
+            .map(when -> (When) visit(when))
+            .collect(Collectors.toList());
     UnresolvedExpression elseStatement = (ctx.elseArg == null) ? null : visit(ctx.elseArg);
 
     return new Case(caseValue, whenStatements, elseStatement);
@@ -433,23 +402,19 @@ public UnresolvedExpression visitCaseFuncAlternative(CaseFuncAlternativeContext
   }
 
   @Override
-  public UnresolvedExpression visitDataTypeFunctionCall(
-      DataTypeFunctionCallContext ctx) {
+  public UnresolvedExpression visitDataTypeFunctionCall(DataTypeFunctionCallContext ctx) {
     return new Cast(visit(ctx.expression()), visit(ctx.convertedDataType()));
   }
 
   @Override
-  public UnresolvedExpression visitConvertedDataType(
-      ConvertedDataTypeContext ctx) {
+  public UnresolvedExpression visitConvertedDataType(ConvertedDataTypeContext ctx) {
     return AstDSL.stringLiteral(ctx.getText());
   }
 
   @Override
-  public UnresolvedExpression visitNoFieldRelevanceFunction(
-          NoFieldRelevanceFunctionContext ctx) {
+  public UnresolvedExpression visitNoFieldRelevanceFunction(NoFieldRelevanceFunctionContext ctx) {
     return new Function(
-            ctx.noFieldRelevanceFunctionName().getText().toLowerCase(),
-            noFieldRelevanceArguments(ctx));
+        ctx.noFieldRelevanceFunctionName().getText().toLowerCase(), noFieldRelevanceArguments(ctx));
   }
 
   @Override
@@ -475,10 +440,9 @@ public UnresolvedExpression visitMultiFieldRelevanceFunction(
     // 'MULTI_MATCH('query'='query_val', 'fields'='*fields_val')'
     String funcName = StringUtils.unquoteText(ctx.multiFieldRelevanceFunctionName().getText());
     if ((funcName.equalsIgnoreCase(BuiltinFunctionName.MULTI_MATCH.toString())
-        || funcName.equalsIgnoreCase(BuiltinFunctionName.MULTIMATCH.toString())
-        || funcName.equalsIgnoreCase(BuiltinFunctionName.MULTIMATCHQUERY.toString()))
-        && !ctx.getRuleContexts(AlternateMultiMatchQueryContext.class)
-        .isEmpty()) {
+            || funcName.equalsIgnoreCase(BuiltinFunctionName.MULTIMATCH.toString())
+            || funcName.equalsIgnoreCase(BuiltinFunctionName.MULTIMATCHQUERY.toString()))
+        && !ctx.getRuleContexts(AlternateMultiMatchQueryContext.class).isEmpty()) {
       return new Function(
           ctx.multiFieldRelevanceFunctionName().getText().toLowerCase(),
           alternateMultiMatchArguments(ctx));
@@ -511,78 +475,81 @@ public UnresolvedExpression visitScoreRelevanceFunction(ScoreRelevanceFunctionCo
     return new ScoreFunction(visit(ctx.relevanceFunction()), weight);
   }
 
-  private Function buildFunction(String functionName,
-                                 List arg) {
+  private Function buildFunction(String functionName, List arg) {
     return new Function(
-        functionName,
-        arg
-            .stream()
-            .map(this::visitFunctionArg)
-            .collect(Collectors.toList())
-    );
+        functionName, arg.stream().map(this::visitFunctionArg).collect(Collectors.toList()));
   }
 
   @Override
   public UnresolvedExpression visitExtractFunctionCall(ExtractFunctionCallContext ctx) {
     return new Function(
-        ctx.extractFunction().EXTRACT().toString(),
-        getExtractFunctionArguments(ctx));
+        ctx.extractFunction().EXTRACT().toString(), getExtractFunctionArguments(ctx));
   }
 
-
   private QualifiedName visitIdentifiers(List identifiers) {
     return new QualifiedName(
         identifiers.stream()
-                   .map(RuleContext::getText)
-                   .map(StringUtils::unquoteIdentifier)
-                   .collect(Collectors.toList()));
+            .map(RuleContext::getText)
+            .map(StringUtils::unquoteIdentifier)
+            .collect(Collectors.toList()));
   }
 
-  private void fillRelevanceArgs(List args,
-                                 ImmutableList.Builder builder) {
+  private void fillRelevanceArgs(
+      List args, ImmutableList.Builder builder) {
     // To support old syntax we must support argument keys as quoted strings.
-    args.forEach(v -> builder.add(v.argName == null
-        ? new UnresolvedArgument(v.relevanceArgName().getText().toLowerCase(),
-            new Literal(StringUtils.unquoteText(v.relevanceArgValue().getText()),
-            DataType.STRING))
-        : new UnresolvedArgument(StringUtils.unquoteText(v.argName.getText()).toLowerCase(),
-            new Literal(StringUtils.unquoteText(v.argVal.getText()), DataType.STRING))));
+    args.forEach(
+        v ->
+            builder.add(
+                v.argName == null
+                    ? new UnresolvedArgument(
+                        v.relevanceArgName().getText().toLowerCase(),
+                        new Literal(
+                            StringUtils.unquoteText(v.relevanceArgValue().getText()),
+                            DataType.STRING))
+                    : new UnresolvedArgument(
+                        StringUtils.unquoteText(v.argName.getText()).toLowerCase(),
+                        new Literal(
+                            StringUtils.unquoteText(v.argVal.getText()), DataType.STRING))));
   }
 
   private List noFieldRelevanceArguments(
-          NoFieldRelevanceFunctionContext ctx) {
+      NoFieldRelevanceFunctionContext ctx) {
     // all the arguments are defaulted to string values
     // to skip environment resolving and function signature resolving
     ImmutableList.Builder builder = ImmutableList.builder();
-    builder.add(new UnresolvedArgument("query",
-            new Literal(StringUtils.unquoteText(ctx.query.getText()), DataType.STRING)));
+    builder.add(
+        new UnresolvedArgument(
+            "query", new Literal(StringUtils.unquoteText(ctx.query.getText()), DataType.STRING)));
     fillRelevanceArgs(ctx.relevanceArg(), builder);
     return builder.build();
   }
 
   private List singleFieldRelevanceArguments(
-        SingleFieldRelevanceFunctionContext ctx) {
+      SingleFieldRelevanceFunctionContext ctx) {
     // all the arguments are defaulted to string values
     // to skip environment resolving and function signature resolving
     ImmutableList.Builder builder = ImmutableList.builder();
-    builder.add(new UnresolvedArgument("field",
-        new QualifiedName(StringUtils.unquoteText(ctx.field.getText()))));
-    builder.add(new UnresolvedArgument("query",
-        new Literal(StringUtils.unquoteText(ctx.query.getText()), DataType.STRING)));
+    builder.add(
+        new UnresolvedArgument(
+            "field", new QualifiedName(StringUtils.unquoteText(ctx.field.getText()))));
+    builder.add(
+        new UnresolvedArgument(
+            "query", new Literal(StringUtils.unquoteText(ctx.query.getText()), DataType.STRING)));
     fillRelevanceArgs(ctx.relevanceArg(), builder);
     return builder.build();
   }
 
-
   private List altSingleFieldRelevanceFunctionArguments(
       AltSingleFieldRelevanceFunctionContext ctx) {
     // all the arguments are defaulted to string values
     // to skip environment resolving and function signature resolving
     ImmutableList.Builder builder = ImmutableList.builder();
-    builder.add(new UnresolvedArgument("field",
-        new QualifiedName(StringUtils.unquoteText(ctx.field.getText()))));
-    builder.add(new UnresolvedArgument("query",
-        new Literal(StringUtils.unquoteText(ctx.query.getText()), DataType.STRING)));
+    builder.add(
+        new UnresolvedArgument(
+            "field", new QualifiedName(StringUtils.unquoteText(ctx.field.getText()))));
+    builder.add(
+        new UnresolvedArgument(
+            "query", new Literal(StringUtils.unquoteText(ctx.query.getText()), DataType.STRING)));
     fillRelevanceArgs(ctx.relevanceArg(), builder);
     return builder.build();
   }
@@ -592,43 +559,45 @@ private List multiFieldRelevanceArguments(
     // all the arguments are defaulted to string values
     // to skip environment resolving and function signature resolving
     ImmutableList.Builder builder = ImmutableList.builder();
-    var fields = new RelevanceFieldList(ctx
-        .getRuleContexts(RelevanceFieldAndWeightContext.class)
-        .stream()
-        .collect(Collectors.toMap(
-            f -> StringUtils.unquoteText(f.field.getText()),
-            f -> (f.weight == null) ? 1F : Float.parseFloat(f.weight.getText()))));
+    var fields =
+        new RelevanceFieldList(
+            ctx.getRuleContexts(RelevanceFieldAndWeightContext.class).stream()
+                .collect(
+                    Collectors.toMap(
+                        f -> StringUtils.unquoteText(f.field.getText()),
+                        f -> (f.weight == null) ? 1F : Float.parseFloat(f.weight.getText()))));
     builder.add(new UnresolvedArgument("fields", fields));
-    builder.add(new UnresolvedArgument("query",
-        new Literal(StringUtils.unquoteText(ctx.query.getText()), DataType.STRING)));
+    builder.add(
+        new UnresolvedArgument(
+            "query", new Literal(StringUtils.unquoteText(ctx.query.getText()), DataType.STRING)));
     fillRelevanceArgs(ctx.relevanceArg(), builder);
     return builder.build();
   }
 
-  private List getFormatFunctionArguments(
-      GetFormatFunctionCallContext ctx) {
-    List args = Arrays.asList(
-        new Literal(ctx.getFormatFunction().getFormatType().getText(), DataType.STRING),
-        visitFunctionArg(ctx.getFormatFunction().functionArg())
-    );
+  private List getFormatFunctionArguments(GetFormatFunctionCallContext ctx) {
+    List args =
+        Arrays.asList(
+            new Literal(ctx.getFormatFunction().getFormatType().getText(), DataType.STRING),
+            visitFunctionArg(ctx.getFormatFunction().functionArg()));
     return args;
   }
 
-  private List timestampFunctionArguments(
-      TimestampFunctionCallContext ctx) {
-    List args = Arrays.asList(
-        new Literal(
-            ctx.timestampFunction().simpleDateTimePart().getText(),
-            DataType.STRING),
-        visitFunctionArg(ctx.timestampFunction().firstArg),
-        visitFunctionArg(ctx.timestampFunction().secondArg)
-    );
+  private List timestampFunctionArguments(TimestampFunctionCallContext ctx) {
+    List args =
+        Arrays.asList(
+            new Literal(ctx.timestampFunction().simpleDateTimePart().getText(), DataType.STRING),
+            visitFunctionArg(ctx.timestampFunction().firstArg),
+            visitFunctionArg(ctx.timestampFunction().secondArg));
     return args;
   }
 
   /**
+   *
+   *
+   * 
    * Adds support for multi_match alternate syntax like
    * MULTI_MATCH('query'='Dale', 'fields'='*name').
+   * 
* * @param ctx : Context for multi field relevance function. * @return : Returns list of all arguments for relevance function. @@ -640,25 +609,32 @@ private List alternateMultiMatchArguments( ImmutableList.Builder builder = ImmutableList.builder(); Map fieldAndWeightMap = new HashMap<>(); - String[] fieldAndWeights = StringUtils.unquoteText( - ctx.getRuleContexts(AlternateMultiMatchFieldContext.class) - .stream().findFirst().get().argVal.getText()).split(","); + String[] fieldAndWeights = + StringUtils.unquoteText( + ctx.getRuleContexts(AlternateMultiMatchFieldContext.class).stream() + .findFirst() + .get() + .argVal + .getText()) + .split(","); for (var fieldAndWeight : fieldAndWeights) { String[] splitFieldAndWeights = fieldAndWeight.split("\\^"); - fieldAndWeightMap.put(splitFieldAndWeights[0], + fieldAndWeightMap.put( + splitFieldAndWeights[0], splitFieldAndWeights.length > 1 ? Float.parseFloat(splitFieldAndWeights[1]) : 1F); } - builder.add(new UnresolvedArgument("fields", - new RelevanceFieldList(fieldAndWeightMap))); - - ctx.getRuleContexts(AlternateMultiMatchQueryContext.class) - .stream().findFirst().ifPresent( - arg -> - builder.add(new UnresolvedArgument("query", + builder.add(new UnresolvedArgument("fields", new RelevanceFieldList(fieldAndWeightMap))); + + ctx.getRuleContexts(AlternateMultiMatchQueryContext.class).stream() + .findFirst() + .ifPresent( + arg -> + builder.add( + new UnresolvedArgument( + "query", new Literal( - StringUtils.unquoteText(arg.argVal.getText()), DataType.STRING))) - ); + StringUtils.unquoteText(arg.argVal.getText()), DataType.STRING)))); fillRelevanceArgs(ctx.relevanceArg(), builder); @@ -674,18 +650,18 @@ private List altMultiFieldRelevanceFunctionArguments( ImmutableList.Builder builder = ImmutableList.builder(); var fields = new RelevanceFieldList(map); builder.add(new UnresolvedArgument("fields", fields)); - builder.add(new UnresolvedArgument("query", - new Literal(StringUtils.unquoteText(ctx.query.getText()), DataType.STRING))); + builder.add( + new UnresolvedArgument( + "query", new Literal(StringUtils.unquoteText(ctx.query.getText()), DataType.STRING))); fillRelevanceArgs(ctx.relevanceArg(), builder); return builder.build(); } - private List getExtractFunctionArguments( - ExtractFunctionCallContext ctx) { - List args = Arrays.asList( - new Literal(ctx.extractFunction().datetimePart().getText(), DataType.STRING), - visitFunctionArg(ctx.extractFunction().functionArg()) - ); + private List getExtractFunctionArguments(ExtractFunctionCallContext ctx) { + List args = + Arrays.asList( + new Literal(ctx.extractFunction().datetimePart().getText(), DataType.STRING), + visitFunctionArg(ctx.extractFunction().functionArg())); return args; } } diff --git a/sql/src/main/java/org/opensearch/sql/sql/parser/AstHavingFilterBuilder.java b/sql/src/main/java/org/opensearch/sql/sql/parser/AstHavingFilterBuilder.java index f90ea2f991..94c11d05af 100644 --- a/sql/src/main/java/org/opensearch/sql/sql/parser/AstHavingFilterBuilder.java +++ b/sql/src/main/java/org/opensearch/sql/sql/parser/AstHavingFilterBuilder.java @@ -3,7 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ - package org.opensearch.sql.sql.parser; import static org.opensearch.sql.sql.antlr.parser.OpenSearchSQLParser.QualifiedNameContext; @@ -13,10 +12,9 @@ import org.opensearch.sql.sql.parser.context.QuerySpecification; /** - * AST Having filter builder that builds HAVING clause condition expressions - * and replace alias by original expression in SELECT clause. - * The reason for this is it's hard to replace afterwards since UnresolvedExpression - * is immutable. + * AST Having filter builder that builds HAVING clause condition expressions and replace alias by + * original expression in SELECT clause. The reason for this is it's hard to replace afterwards + * since UnresolvedExpression is immutable. */ @RequiredArgsConstructor public class AstHavingFilterBuilder extends AstExpressionBuilder { @@ -34,5 +32,4 @@ private UnresolvedExpression replaceAlias(UnresolvedExpression expr) { } return expr; } - } diff --git a/sql/src/main/java/org/opensearch/sql/sql/parser/AstSortBuilder.java b/sql/src/main/java/org/opensearch/sql/sql/parser/AstSortBuilder.java index 1b872dce54..2594709f4f 100644 --- a/sql/src/main/java/org/opensearch/sql/sql/parser/AstSortBuilder.java +++ b/sql/src/main/java/org/opensearch/sql/sql/parser/AstSortBuilder.java @@ -3,7 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ - package org.opensearch.sql.sql.parser; import static org.opensearch.sql.ast.dsl.AstDSL.booleanLiteral; @@ -27,8 +26,8 @@ import org.opensearch.sql.sql.parser.context.QuerySpecification; /** - * AST sort builder that builds Sort AST node from ORDER BY clause. During this process, the item - * in order by may be replaced by item in project list if it's an alias or ordinal. This is same as + * AST sort builder that builds Sort AST node from ORDER BY clause. During this process, the item in + * order by may be replaced by item in project list if it's an alias or ordinal. This is same as * GROUP BY building process. */ @RequiredArgsConstructor @@ -38,9 +37,7 @@ public class AstSortBuilder extends OpenSearchSQLParserBaseVisitor createSortFields() { @@ -57,8 +54,8 @@ private List createSortFields() { } /** - * Argument "asc" is required. - * Argument "nullFirst" is optional and determined by Analyzer later if absent. + * Argument "asc" is required. Argument "nullFirst" is optional and determined by Analyzer later + * if absent. */ private List createSortArguments(SortOption option) { SortOrder sortOrder = option.getSortOrder(); @@ -71,5 +68,4 @@ private List createSortArguments(SortOption option) { } return args.build(); } - } diff --git a/sql/src/main/java/org/opensearch/sql/sql/parser/ParserUtils.java b/sql/src/main/java/org/opensearch/sql/sql/parser/ParserUtils.java index 947dca51b9..3c60d43733 100644 --- a/sql/src/main/java/org/opensearch/sql/sql/parser/ParserUtils.java +++ b/sql/src/main/java/org/opensearch/sql/sql/parser/ParserUtils.java @@ -3,7 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ - package org.opensearch.sql.sql.parser; import static org.opensearch.sql.ast.tree.Sort.NullOrder; @@ -16,33 +15,24 @@ import org.antlr.v4.runtime.Token; import org.antlr.v4.runtime.tree.TerminalNode; -/** - * Parser Utils Class. - */ +/** Parser Utils Class. */ @UtilityClass public class ParserUtils { - /** - * Get original text in query. - */ + /** Get original text in query. */ public static String getTextInQuery(ParserRuleContext ctx, String queryString) { Token start = ctx.getStart(); Token stop = ctx.getStop(); return queryString.substring(start.getStartIndex(), stop.getStopIndex() + 1); } - /** - * Create sort option from syntax tree node. - */ + /** Create sort option from syntax tree node. */ public static SortOption createSortOption(OrderByElementContext orderBy) { return new SortOption( - createSortOrder(orderBy.order), - createNullOrder(orderBy.FIRST(), orderBy.LAST())); + createSortOrder(orderBy.order), createNullOrder(orderBy.FIRST(), orderBy.LAST())); } - /** - * Create sort order for sort option use from ASC/DESC token. - */ + /** Create sort order for sort option use from ASC/DESC token. */ public static SortOrder createSortOrder(Token ctx) { if (ctx == null) { return null; @@ -50,9 +40,7 @@ public static SortOrder createSortOrder(Token ctx) { return SortOrder.valueOf(ctx.getText().toUpperCase()); } - /** - * Create null order for sort option use from FIRST/LAST token. - */ + /** Create null order for sort option use from FIRST/LAST token. */ public static NullOrder createNullOrder(TerminalNode first, TerminalNode last) { if (first != null) { return NullOrder.NULL_FIRST; @@ -62,5 +50,4 @@ public static NullOrder createNullOrder(TerminalNode first, TerminalNode last) { return null; } } - } diff --git a/sql/src/main/java/org/opensearch/sql/sql/parser/context/ParsingContext.java b/sql/src/main/java/org/opensearch/sql/sql/parser/context/ParsingContext.java index 33b313367d..297fdfd749 100644 --- a/sql/src/main/java/org/opensearch/sql/sql/parser/context/ParsingContext.java +++ b/sql/src/main/java/org/opensearch/sql/sql/parser/context/ParsingContext.java @@ -3,21 +3,20 @@ * SPDX-License-Identifier: Apache-2.0 */ - package org.opensearch.sql.sql.parser.context; import java.util.ArrayDeque; import java.util.Deque; /** - * SQL parsing context that maintains stack of query specifications for nested queries. - * Currently this is just a thin wrapper by a stack. + * SQL parsing context that maintains stack of query specifications for nested queries. Currently + * this is just a thin wrapper by a stack. */ public class ParsingContext { /** - * Use stack rather than linked query specification because there is no need - * to look up through the stack. + * Use stack rather than linked query specification because there is no need to look up through + * the stack. */ private final Deque contexts = new ArrayDeque<>(); @@ -31,10 +30,10 @@ public QuerySpecification peek() { /** * Pop up query context. - * @return query context after popup. + * + * @return query context after popup. */ public QuerySpecification pop() { return contexts.pop(); } - } diff --git a/sql/src/main/java/org/opensearch/sql/sql/parser/context/QuerySpecification.java b/sql/src/main/java/org/opensearch/sql/sql/parser/context/QuerySpecification.java index 21dddde2b9..5625371f05 100644 --- a/sql/src/main/java/org/opensearch/sql/sql/parser/context/QuerySpecification.java +++ b/sql/src/main/java/org/opensearch/sql/sql/parser/context/QuerySpecification.java @@ -3,7 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ - package org.opensearch.sql.sql.parser.context; import static org.opensearch.sql.sql.antlr.parser.OpenSearchSQLParser.FilteredAggregationFunctionCallContext; @@ -42,6 +41,7 @@ /** * Query specification domain that collects basic info for a simple query. + * *
  * (I) What is the impact of this new abstraction?
  *  This abstraction and collecting process turns AST building process into two phases:
@@ -61,10 +61,9 @@
 @ToString
 public class QuerySpecification {
 
-  /**
-   * Items in SELECT clause and mapping from alias to select item.
-   */
+  /** Items in SELECT clause and mapping from alias to select item. */
   private final List selectItems = new ArrayList<>();
+
   private final Map selectItemsByAlias = new HashMap<>();
 
   /**
@@ -74,31 +73,36 @@ public class QuerySpecification {
   private final Set aggregators = new LinkedHashSet<>();
 
   /**
+   *
+   *
+   * 
    * Items in GROUP BY clause that may be:
    *  1) Simple field name
    *  2) Field nested in scalar function call
    *  3) Ordinal that points to expression in SELECT
    *  4) Alias that points to expression in SELECT.
+   *  
*/ private final List groupByItems = new ArrayList<>(); - /** - * Items in ORDER BY clause that may be different forms as above and its options. - */ + /** Items in ORDER BY clause that may be different forms as above and its options. */ private final List orderByItems = new ArrayList<>(); + private final List orderByOptions = new ArrayList<>(); /** * Collect all query information in the parse tree excluding info in sub-query). - * @param query query spec node in parse tree + * + * @param query query spec node in parse tree */ public void collect(QuerySpecificationContext query, String queryString) { query.accept(new QuerySpecificationCollector(queryString)); } /** - * Replace unresolved expression if it's an alias or ordinal that represents - * an actual expression in SELECT list. + * Replace unresolved expression if it's an alias or ordinal that represents an actual expression + * in SELECT list. + * * @param expr item to be replaced * @return select item that the given expr represents */ @@ -118,8 +122,8 @@ private boolean isIntegerLiteral(UnresolvedExpression expr) { } if (((Literal) expr).getType() != DataType.INTEGER) { - throw new SemanticCheckException(StringUtils.format( - "Non-integer constant [%s] found in ordinal", expr)); + throw new SemanticCheckException( + StringUtils.format("Non-integer constant [%s] found in ordinal", expr)); } return true; } @@ -127,25 +131,26 @@ private boolean isIntegerLiteral(UnresolvedExpression expr) { private UnresolvedExpression getSelectItemByOrdinal(UnresolvedExpression expr) { int ordinal = (Integer) ((Literal) expr).getValue(); if (ordinal <= 0 || ordinal > selectItems.size()) { - throw new SemanticCheckException(StringUtils.format( - "Ordinal [%d] is out of bound of select item list", ordinal)); + throw new SemanticCheckException( + StringUtils.format("Ordinal [%d] is out of bound of select item list", ordinal)); } return selectItems.get(ordinal - 1); } /** * Check if an expression is a select alias. - * @param expr expression + * + * @param expr expression * @return true if it's an alias */ public boolean isSelectAlias(UnresolvedExpression expr) { - return (expr instanceof QualifiedName) - && (selectItemsByAlias.containsKey(expr.toString())); + return (expr instanceof QualifiedName) && (selectItemsByAlias.containsKey(expr.toString())); } /** * Get original expression aliased in SELECT clause. - * @param expr alias + * + * @param expr alias * @return expression in SELECT */ public UnresolvedExpression getSelectItemByAlias(UnresolvedExpression expr) { @@ -223,8 +228,7 @@ public Void visitAggregateFunctionCall(AggregateFunctionCallContext ctx) { @Override public Void visitFilteredAggregationFunctionCall(FilteredAggregationFunctionCallContext ctx) { UnresolvedExpression aggregateFunction = visitAstExpression(ctx); - aggregators.add( - AstDSL.alias(getTextInQuery(ctx, queryString), aggregateFunction)); + aggregators.add(AstDSL.alias(getTextInQuery(ctx, queryString), aggregateFunction)); return super.visitFilteredAggregationFunctionCall(ctx); } @@ -236,5 +240,4 @@ private UnresolvedExpression visitAstExpression(ParseTree tree) { return expressionBuilder.visit(tree); } } - } diff --git a/sql/src/test/java/org/opensearch/sql/common/antlr/SyntaxParserTestBase.java b/sql/src/test/java/org/opensearch/sql/common/antlr/SyntaxParserTestBase.java index 63d7666c62..87f2083774 100644 --- a/sql/src/test/java/org/opensearch/sql/common/antlr/SyntaxParserTestBase.java +++ b/sql/src/test/java/org/opensearch/sql/common/antlr/SyntaxParserTestBase.java @@ -7,16 +7,14 @@ import lombok.Getter; import lombok.RequiredArgsConstructor; -/** - * A base class for tests for SQL or PPL parser. - */ +/** A base class for tests for SQL or PPL parser. */ @RequiredArgsConstructor(access = AccessLevel.PROTECTED) public abstract class SyntaxParserTestBase { - @Getter - private final Parser parser; + @Getter private final Parser parser; /** * A helper function that fails a test if the parser rejects a given query. + * * @param query Query to test. */ protected void acceptQuery(String query) { @@ -25,6 +23,7 @@ protected void acceptQuery(String query) { /** * A helper function that fails a test if the parser accepts a given query. + * * @param query Query to test. */ protected void rejectQuery(String query) { diff --git a/sql/src/test/java/org/opensearch/sql/sql/SQLServiceTest.java b/sql/src/test/java/org/opensearch/sql/sql/SQLServiceTest.java index f4342d877d..8cb2994dc3 100644 --- a/sql/src/test/java/org/opensearch/sql/sql/SQLServiceTest.java +++ b/sql/src/test/java/org/opensearch/sql/sql/SQLServiceTest.java @@ -3,7 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ - package org.opensearch.sql.sql; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -45,14 +44,13 @@ class SQLServiceTest { private DefaultQueryManager queryManager; - @Mock - private QueryService queryService; + @Mock private QueryService queryService; @BeforeEach public void setUp() { queryManager = DefaultQueryManager.defaultQueryManager(); - sqlService = new SQLService(new SQLSyntaxParser(), queryManager, - new QueryPlanFactory(queryService)); + sqlService = + new SQLService(new SQLSyntaxParser(), queryManager, new QueryPlanFactory(queryService)); } @AfterEach @@ -97,8 +95,8 @@ public void onFailure(Exception e) { @Test public void can_execute_close_cursor_query() { sqlService.execute( - new SQLQueryRequest(new JSONObject(), null, QUERY + "/close", - Map.of("format", "jdbc"), "n:cursor"), + new SQLQueryRequest( + new JSONObject(), null, QUERY + "/close", Map.of("format", "jdbc"), "n:cursor"), new ResponseListener<>() { @Override public void onResponse(QueryResponse response) { @@ -131,13 +129,17 @@ public void onFailure(Exception e) { @Test public void can_explain_sql_query() { - doAnswer(invocation -> { - ResponseListener listener = invocation.getArgument(1); - listener.onResponse(new ExplainResponse(new ExplainResponseNode("Test"))); - return null; - }).when(queryService).explain(any(), any()); + doAnswer( + invocation -> { + ResponseListener listener = invocation.getArgument(1); + listener.onResponse(new ExplainResponse(new ExplainResponseNode("Test"))); + return null; + }) + .when(queryService) + .explain(any(), any()); - sqlService.explain(new SQLQueryRequest(new JSONObject(), "SELECT 123", EXPLAIN, "csv"), + sqlService.explain( + new SQLQueryRequest(new JSONObject(), "SELECT 123", EXPLAIN, "csv"), new ResponseListener() { @Override public void onResponse(ExplainResponse response) { @@ -153,8 +155,8 @@ public void onFailure(Exception e) { @Test public void cannot_explain_cursor_query() { - sqlService.explain(new SQLQueryRequest(new JSONObject(), null, EXPLAIN, - Map.of("format", "jdbc"), "n:cursor"), + sqlService.explain( + new SQLQueryRequest(new JSONObject(), null, EXPLAIN, Map.of("format", "jdbc"), "n:cursor"), new ResponseListener() { @Override public void onResponse(ExplainResponse response) { @@ -163,8 +165,10 @@ public void onResponse(ExplainResponse response) { @Override public void onFailure(Exception e) { - assertEquals("Explain of a paged query continuation is not supported." - + " Use `explain` for the initial query request.", e.getMessage()); + assertEquals( + "Explain of a paged query continuation is not supported." + + " Use `explain` for the initial query request.", + e.getMessage()); } }); } diff --git a/sql/src/test/java/org/opensearch/sql/sql/antlr/BracketedTimestampTest.java b/sql/src/test/java/org/opensearch/sql/sql/antlr/BracketedTimestampTest.java index 0f7a284aa7..120cd233fc 100644 --- a/sql/src/test/java/org/opensearch/sql/sql/antlr/BracketedTimestampTest.java +++ b/sql/src/test/java/org/opensearch/sql/sql/antlr/BracketedTimestampTest.java @@ -3,7 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ - package org.opensearch.sql.sql.antlr; import org.junit.jupiter.api.Test; diff --git a/sql/src/test/java/org/opensearch/sql/sql/antlr/HighlightTest.java b/sql/src/test/java/org/opensearch/sql/sql/antlr/HighlightTest.java index 6826a37c0b..ae1e418357 100644 --- a/sql/src/test/java/org/opensearch/sql/sql/antlr/HighlightTest.java +++ b/sql/src/test/java/org/opensearch/sql/sql/antlr/HighlightTest.java @@ -15,14 +15,14 @@ void single_field_test() { @Test void multiple_highlights_test() { - acceptQuery("SELECT HIGHLIGHT(Tags), HIGHLIGHT(Body) FROM Index " - + "WHERE MULTI_MATCH([Tags, Body], 'Time')"); + acceptQuery( + "SELECT HIGHLIGHT(Tags), HIGHLIGHT(Body) FROM Index " + + "WHERE MULTI_MATCH([Tags, Body], 'Time')"); } @Test void wildcard_test() { - acceptQuery("SELECT HIGHLIGHT('T*') FROM Index " - + "WHERE MULTI_MATCH([Tags, Body], 'Time')"); + acceptQuery("SELECT HIGHLIGHT('T*') FROM Index " + "WHERE MULTI_MATCH([Tags, Body], 'Time')"); } @Test @@ -33,13 +33,12 @@ void highlight_all_test() { @Test void multiple_parameters_failure_test() { - rejectQuery("SELECT HIGHLIGHT(Tags1, Tags2) FROM Index " - + "WHERE MULTI_MATCH([Tags, Body], 'Time')"); + rejectQuery( + "SELECT HIGHLIGHT(Tags1, Tags2) FROM Index " + "WHERE MULTI_MATCH([Tags, Body], 'Time')"); } @Test void no_parameters_failure_test() { - rejectQuery("SELECT HIGHLIGHT() FROM Index " - + "WHERE MULTI_MATCH([Tags, Body], 'Time')"); + rejectQuery("SELECT HIGHLIGHT() FROM Index " + "WHERE MULTI_MATCH([Tags, Body], 'Time')"); } } diff --git a/sql/src/test/java/org/opensearch/sql/sql/antlr/MatchBoolPrefixParserTest.java b/sql/src/test/java/org/opensearch/sql/sql/antlr/MatchBoolPrefixParserTest.java index 66c4d5be9d..db5ce18edb 100644 --- a/sql/src/test/java/org/opensearch/sql/sql/antlr/MatchBoolPrefixParserTest.java +++ b/sql/src/test/java/org/opensearch/sql/sql/antlr/MatchBoolPrefixParserTest.java @@ -25,14 +25,13 @@ static Stream generateValidArguments() { new String("max_expansions=50"), new String("fuzzy_transpositions=true"), new String("fuzzy_rewrite=constant_score"), - new String("boost=1") - ); + new String("boost=1")); } @ParameterizedTest @MethodSource("generateValidArguments") public void testValidArguments(String arg) { - acceptQuery("SELECT * FROM T WHERE MATCH_BOOL_PREFIX(message, 'query', " + arg + ")"); + acceptQuery("SELECT * FROM T WHERE MATCH_BOOL_PREFIX(message, 'query', " + arg + ")"); } @Test diff --git a/sql/src/test/java/org/opensearch/sql/sql/antlr/SQLParserTest.java b/sql/src/test/java/org/opensearch/sql/sql/antlr/SQLParserTest.java index 3f323725ab..db091a4932 100644 --- a/sql/src/test/java/org/opensearch/sql/sql/antlr/SQLParserTest.java +++ b/sql/src/test/java/org/opensearch/sql/sql/antlr/SQLParserTest.java @@ -3,7 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ - package org.opensearch.sql.sql.antlr; import org.opensearch.sql.common.antlr.SyntaxParserTestBase; diff --git a/sql/src/test/java/org/opensearch/sql/sql/antlr/SQLSyntaxParserTest.java b/sql/src/test/java/org/opensearch/sql/sql/antlr/SQLSyntaxParserTest.java index ade4983f58..948675221a 100644 --- a/sql/src/test/java/org/opensearch/sql/sql/antlr/SQLSyntaxParserTest.java +++ b/sql/src/test/java/org/opensearch/sql/sql/antlr/SQLSyntaxParserTest.java @@ -3,7 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ - package org.opensearch.sql.sql.antlr; import static org.junit.jupiter.api.Assertions.assertAll; @@ -73,8 +72,7 @@ public void canParseHiddenIndexName() { @Test public void canNotParseIndexNameWithSpecialChar() { - assertThrows(SyntaxCheckException.class, - () -> parser.parse("SELECT * FROM hello+world")); + assertThrows(SyntaxCheckException.class, () -> parser.parse("SELECT * FROM hello+world")); } @Test @@ -84,14 +82,12 @@ public void canParseIndexNameWithSpecialCharQuoted() { @Test public void canNotParseIndexNameStartingWithNumber() { - assertThrows(SyntaxCheckException.class, - () -> parser.parse("SELECT * FROM 123test")); + assertThrows(SyntaxCheckException.class, () -> parser.parse("SELECT * FROM 123test")); } @Test public void canNotParseIndexNameSingleQuoted() { - assertThrows(SyntaxCheckException.class, - () -> parser.parse("SELECT * FROM 'test'")); + assertThrows(SyntaxCheckException.class, () -> parser.parse("SELECT * FROM 'test'")); } @Test @@ -101,14 +97,15 @@ public void canParseWhereClause() { @Test public void canParseSelectClauseWithLogicalOperator() { - assertNotNull(parser.parse( - "SELECT age = 10 AND name = 'John' OR NOT (balance > 1000) FROM test")); + assertNotNull( + parser.parse("SELECT age = 10 AND name = 'John' OR NOT (balance > 1000) FROM test")); } @Test public void canParseWhereClauseWithLogicalOperator() { - assertNotNull(parser.parse("SELECT name FROM test " - + "WHERE age = 10 AND name = 'John' OR NOT (balance > 1000)")); + assertNotNull( + parser.parse( + "SELECT name FROM test " + "WHERE age = 10 AND name = 'John' OR NOT (balance > 1000)")); } @Test @@ -128,9 +125,11 @@ public void canParseDistinctClause() { @Test public void canParseCaseStatement() { assertNotNull(parser.parse("SELECT CASE WHEN age > 30 THEN 'age1' ELSE 'age2' END FROM test")); - assertNotNull(parser.parse("SELECT CASE WHEN age > 30 THEN 'age1' " - + " WHEN age < 50 THEN 'age2' " - + " ELSE 'age3' END FROM test")); + assertNotNull( + parser.parse( + "SELECT CASE WHEN age > 30 THEN 'age1' " + + " WHEN age < 50 THEN 'age2' " + + " ELSE 'age3' END FROM test")); assertNotNull(parser.parse("SELECT CASE age WHEN 30 THEN 'age1' ELSE 'age2' END FROM test")); assertNotNull(parser.parse("SELECT CASE age WHEN 30 THEN 'age1' END FROM test")); } @@ -147,10 +146,11 @@ public void canNotParseAggregateFunctionWithWrongArgument() { public void canParseOrderByClause() { assertNotNull(parser.parse("SELECT name, age FROM test ORDER BY name, age")); assertNotNull(parser.parse("SELECT name, age FROM test ORDER BY name ASC, age DESC")); - assertNotNull(parser.parse( - "SELECT name, age FROM test ORDER BY name NULLS LAST, age NULLS FIRST")); - assertNotNull(parser.parse( - "SELECT name, age FROM test ORDER BY name ASC NULLS FIRST, age DESC NULLS LAST")); + assertNotNull( + parser.parse("SELECT name, age FROM test ORDER BY name NULLS LAST, age NULLS FIRST")); + assertNotNull( + parser.parse( + "SELECT name, age FROM test ORDER BY name ASC NULLS FIRST, age DESC NULLS LAST")); } @Test @@ -171,8 +171,7 @@ private static Stream nowLikeFunctionsData() { Arguments.of("current_date", false, true), Arguments.of("utc_date", false, true), Arguments.of("utc_time", false, true), - Arguments.of("utc_timestamp", false, true) - ); + Arguments.of("utc_timestamp", false, true)); } private static Stream getPartForExtractFunction() { @@ -196,8 +195,7 @@ private static Stream getPartForExtractFunction() { Arguments.of("DAY_SECOND"), Arguments.of("DAY_MINUTE"), Arguments.of("DAY_HOUR"), - Arguments.of("YEAR_MONTH") - ); + Arguments.of("YEAR_MONTH")); } @ParameterizedTest(name = "{0}") @@ -207,11 +205,7 @@ public void can_parse_extract_function(String part) { } private static Stream getInvalidPartForExtractFunction() { - return Stream.of( - Arguments.of("INVALID"), - Arguments.of("\"SECOND\""), - Arguments.of("123") - ); + return Stream.of(Arguments.of("INVALID"), Arguments.of("\"SECOND\""), Arguments.of("123")); } @ParameterizedTest(name = "{0}") @@ -231,9 +225,12 @@ public void can_parse_weekday_function() { @ParameterizedTest(name = "{0}") @MethodSource("nowLikeFunctionsData") public void can_parse_now_like_functions(String name, Boolean hasFsp, Boolean hasShortcut) { - var calls = new ArrayList() {{ - add(name + "()"); - }}; + var calls = + new ArrayList() { + { + add(name + "()"); + } + }; if (hasShortcut) { calls.add(name); } @@ -270,8 +267,7 @@ public void can_parse_get_format_function(String type, String format) { @Test public void cannot_parse_get_format_function_with_bad_arg() { assertThrows( - SyntaxCheckException.class, - () -> parser.parse("GET_FORMAT(NONSENSE_ARG,'INTERNAL')")); + SyntaxCheckException.class, () -> parser.parse("GET_FORMAT(NONSENSE_ARG,'INTERNAL')")); } @Test @@ -326,53 +322,55 @@ public void can_parse_month_of_year_function() { assertNotNull(parser.parse("SELECT month(timestamp('2022-11-18 00:00:00'))")); assertNotNull(parser.parse("SELECT month_of_year(timestamp('2022-11-18 00:00:00'))")); - } @Test public void can_parse_multi_match_relevance_function() { - assertNotNull(parser.parse( - "SELECT id FROM test WHERE multimatch(\"fields\"=\"field\", query=\"query\")")); - assertNotNull(parser.parse( - "SELECT id FROM test WHERE multimatchquery(fields=\"field\", \"query\"=\"query\")")); - assertNotNull(parser.parse( - "SELECT id FROM test WHERE multi_match(\"fields\"=\"field\", \"query\"=\"query\")")); - assertNotNull(parser.parse( - "SELECT id FROM test WHERE multi_match(\'fields\'=\'field\', \'query\'=\'query\')")); - assertNotNull(parser.parse( - "SELECT id FROM test WHERE multi_match(fields=\'field\', query=\'query\')")); - assertNotNull(parser.parse( - "SELECT id FROM test WHERE multi_match(['address'], 'query')")); - assertNotNull(parser.parse( - "SELECT id FROM test WHERE multi_match(['address', 'notes'], 'query')")); - assertNotNull(parser.parse( - "SELECT id FROM test WHERE multi_match([\"*\"], 'query')")); - assertNotNull(parser.parse( - "SELECT id FROM test WHERE multi_match([\"address\"], 'query')")); - assertNotNull(parser.parse( - "SELECT id FROM test WHERE multi_match([`address`], 'query')")); - assertNotNull(parser.parse( - "SELECT id FROM test WHERE multi_match([address], 'query')")); - - assertNotNull(parser.parse( - "SELECT id FROM test WHERE" - + " multi_match(['address' ^ 1.0, 'notes' ^ 2.2], 'query')")); - assertNotNull(parser.parse( - "SELECT id FROM test WHERE multi_match(['address' ^ 1.1, 'notes'], 'query')")); - assertNotNull(parser.parse( - "SELECT id FROM test WHERE multi_match(['address', 'notes' ^ 1.5], 'query')")); - assertNotNull(parser.parse( - "SELECT id FROM test WHERE multi_match(['address', 'notes' 3], 'query')")); - assertNotNull(parser.parse( - "SELECT id FROM test WHERE multi_match(['address' ^ .3, 'notes' 3], 'query')")); - - assertNotNull(parser.parse( - "SELECT id FROM test WHERE" - + " multi_match([\"Tags\" ^ 1.5, Title, `Body` 4.2], 'query')")); - assertNotNull(parser.parse( - "SELECT id FROM test WHERE" - + " multi_match([\"Tags\" ^ 1.5, Title, `Body` 4.2], 'query', analyzer=keyword," - + "operator='AND', tie_breaker=0.3, type = \"most_fields\", fuzziness = \"AUTO\")")); + assertNotNull( + parser.parse( + "SELECT id FROM test WHERE multimatch(\"fields\"=\"field\", query=\"query\")")); + assertNotNull( + parser.parse( + "SELECT id FROM test WHERE multimatchquery(fields=\"field\", \"query\"=\"query\")")); + assertNotNull( + parser.parse( + "SELECT id FROM test WHERE multi_match(\"fields\"=\"field\", \"query\"=\"query\")")); + assertNotNull( + parser.parse( + "SELECT id FROM test WHERE multi_match(\'fields\'=\'field\', \'query\'=\'query\')")); + assertNotNull( + parser.parse("SELECT id FROM test WHERE multi_match(fields=\'field\', query=\'query\')")); + assertNotNull(parser.parse("SELECT id FROM test WHERE multi_match(['address'], 'query')")); + assertNotNull( + parser.parse("SELECT id FROM test WHERE multi_match(['address', 'notes'], 'query')")); + assertNotNull(parser.parse("SELECT id FROM test WHERE multi_match([\"*\"], 'query')")); + assertNotNull(parser.parse("SELECT id FROM test WHERE multi_match([\"address\"], 'query')")); + assertNotNull(parser.parse("SELECT id FROM test WHERE multi_match([`address`], 'query')")); + assertNotNull(parser.parse("SELECT id FROM test WHERE multi_match([address], 'query')")); + + assertNotNull( + parser.parse( + "SELECT id FROM test WHERE" + + " multi_match(['address' ^ 1.0, 'notes' ^ 2.2], 'query')")); + assertNotNull( + parser.parse("SELECT id FROM test WHERE multi_match(['address' ^ 1.1, 'notes'], 'query')")); + assertNotNull( + parser.parse("SELECT id FROM test WHERE multi_match(['address', 'notes' ^ 1.5], 'query')")); + assertNotNull( + parser.parse("SELECT id FROM test WHERE multi_match(['address', 'notes' 3], 'query')")); + assertNotNull( + parser.parse( + "SELECT id FROM test WHERE multi_match(['address' ^ .3, 'notes' 3], 'query')")); + + assertNotNull( + parser.parse( + "SELECT id FROM test WHERE" + + " multi_match([\"Tags\" ^ 1.5, Title, `Body` 4.2], 'query')")); + assertNotNull( + parser.parse( + "SELECT id FROM test WHERE multi_match([\"Tags\" ^ 1.5, Title, `Body` 4.2], 'query'," + + " analyzer=keyword,operator='AND', tie_breaker=0.3, type = \"most_fields\"," + + " fuzziness = \"AUTO\")")); } @Test @@ -385,160 +383,137 @@ public void can_parse_second_functions() { @Test public void can_parse_simple_query_string_relevance_function() { - assertNotNull(parser.parse( - "SELECT id FROM test WHERE simple_query_string(['address'], 'query')")); - assertNotNull(parser.parse( - "SELECT id FROM test WHERE simple_query_string(['address', 'notes'], 'query')")); - assertNotNull(parser.parse( - "SELECT id FROM test WHERE simple_query_string([\"*\"], 'query')")); - assertNotNull(parser.parse( - "SELECT id FROM test WHERE simple_query_string([\"address\"], 'query')")); - assertNotNull(parser.parse( - "SELECT id FROM test WHERE simple_query_string([`address`], 'query')")); - assertNotNull(parser.parse( - "SELECT id FROM test WHERE simple_query_string([address], 'query')")); - - assertNotNull(parser.parse( - "SELECT id FROM test WHERE" - + " simple_query_string(['address' ^ 1.0, 'notes' ^ 2.2], 'query')")); - assertNotNull(parser.parse( - "SELECT id FROM test WHERE simple_query_string(['address' ^ 1.1, 'notes'], 'query')")); - assertNotNull(parser.parse( - "SELECT id FROM test WHERE simple_query_string(['address', 'notes' ^ 1.5], 'query')")); - assertNotNull(parser.parse( - "SELECT id FROM test WHERE simple_query_string(['address', 'notes' 3], 'query')")); - assertNotNull(parser.parse( - "SELECT id FROM test WHERE simple_query_string(['address' ^ .3, 'notes' 3], 'query')")); - - assertNotNull(parser.parse( - "SELECT id FROM test WHERE" - + " simple_query_string([\"Tags\" ^ 1.5, Title, `Body` 4.2], 'query')")); - assertNotNull(parser.parse( - "SELECT id FROM test WHERE" - + " simple_query_string([\"Tags\" ^ 1.5, Title, `Body` 4.2], 'query', analyzer=keyword," - + "flags='AND', quote_field_suffix=\".exact\", fuzzy_prefix_length = 4)")); + assertNotNull( + parser.parse("SELECT id FROM test WHERE simple_query_string(['address'], 'query')")); + assertNotNull( + parser.parse( + "SELECT id FROM test WHERE simple_query_string(['address', 'notes'], 'query')")); + assertNotNull(parser.parse("SELECT id FROM test WHERE simple_query_string([\"*\"], 'query')")); + assertNotNull( + parser.parse("SELECT id FROM test WHERE simple_query_string([\"address\"], 'query')")); + assertNotNull( + parser.parse("SELECT id FROM test WHERE simple_query_string([`address`], 'query')")); + assertNotNull( + parser.parse("SELECT id FROM test WHERE simple_query_string([address], 'query')")); + + assertNotNull( + parser.parse( + "SELECT id FROM test WHERE" + + " simple_query_string(['address' ^ 1.0, 'notes' ^ 2.2], 'query')")); + assertNotNull( + parser.parse( + "SELECT id FROM test WHERE simple_query_string(['address' ^ 1.1, 'notes'], 'query')")); + assertNotNull( + parser.parse( + "SELECT id FROM test WHERE simple_query_string(['address', 'notes' ^ 1.5], 'query')")); + assertNotNull( + parser.parse( + "SELECT id FROM test WHERE simple_query_string(['address', 'notes' 3], 'query')")); + assertNotNull( + parser.parse( + "SELECT id FROM test WHERE simple_query_string(['address' ^ .3, 'notes' 3], 'query')")); + + assertNotNull( + parser.parse( + "SELECT id FROM test WHERE" + + " simple_query_string([\"Tags\" ^ 1.5, Title, `Body` 4.2], 'query')")); + assertNotNull( + parser.parse( + "SELECT id FROM test WHERE simple_query_string([\"Tags\" ^ 1.5, Title, `Body` 4.2]," + + " 'query', analyzer=keyword,flags='AND', quote_field_suffix=\".exact\"," + + " fuzzy_prefix_length = 4)")); } @Test public void can_parse_str_to_date() { - assertNotNull(parser.parse( - "SELECT STR_TO_DATE('01,5,2013','%d,%m,%Y')" - )); + assertNotNull(parser.parse("SELECT STR_TO_DATE('01,5,2013','%d,%m,%Y')")); - assertNotNull(parser.parse( - "SELECT STR_TO_DATE('a09:30:17','a%h:%i:%s')" - )); + assertNotNull(parser.parse("SELECT STR_TO_DATE('a09:30:17','a%h:%i:%s')")); - assertNotNull(parser.parse( - "SELECT STR_TO_DATE('abc','abc');" - )); + assertNotNull(parser.parse("SELECT STR_TO_DATE('abc','abc');")); } @Test public void can_parse_query_string_relevance_function() { - assertNotNull(parser.parse( - "SELECT id FROM test WHERE query_string(['*'], 'query')")); - assertNotNull(parser.parse( - "SELECT id FROM test WHERE query_string(['address'], 'query')")); - assertNotNull(parser.parse( - "SELECT id FROM test WHERE query_string(['add*'], 'query')")); - assertNotNull(parser.parse( - "SELECT id FROM test WHERE query_string(['*ess'], 'query')")); - assertNotNull(parser.parse( - "SELECT id FROM test WHERE query_string(['address', 'notes'], 'query')")); - assertNotNull(parser.parse( - "SELECT id FROM test WHERE query_string([\"*\"], 'query')")); - assertNotNull(parser.parse( - "SELECT id FROM test WHERE query_string([\"address\"], 'query')")); - assertNotNull(parser.parse( - "SELECT id FROM test WHERE query_string([\"ad*\"], 'query')")); - assertNotNull(parser.parse( - "SELECT id FROM test WHERE query_string([\"*s\"], 'query')")); - assertNotNull(parser.parse( - "SELECT id FROM test WHERE query_string([\"address\", \"notes\"], 'query')")); - assertNotNull(parser.parse( - "SELECT id FROM test WHERE query_string([`*`], 'query')")); - assertNotNull(parser.parse( - "SELECT id FROM test WHERE query_string([`address`], 'query')")); - assertNotNull(parser.parse( - "SELECT id FROM test WHERE query_string([`ad*`], 'query')")); - assertNotNull(parser.parse( - "SELECT id FROM test WHERE query_string([`*ss`], 'query')")); - assertNotNull(parser.parse( - "SELECT id FROM test WHERE query_string([`address`, `notes`], 'query')")); - assertNotNull(parser.parse( - "SELECT id FROM test WHERE query_string([address], 'query')")); - assertNotNull(parser.parse( - "SELECT id FROM test WHERE query_string([addr*], 'query')")); - assertNotNull(parser.parse( - "SELECT id FROM test WHERE query_string([*ss], 'query')")); - assertNotNull(parser.parse( - "SELECT id FROM test WHERE query_string([address, notes], 'query')")); - - assertNotNull(parser.parse( - "SELECT id FROM test WHERE" - + " query_string(['address' ^ 1.0, 'notes' ^ 2.2], 'query')")); - assertNotNull(parser.parse( - "SELECT id FROM test WHERE query_string(['address' ^ 1.1, 'notes'], 'query')")); - assertNotNull(parser.parse( - "SELECT id FROM test WHERE query_string(['address', 'notes' ^ 1.5], 'query')")); - assertNotNull(parser.parse( - "SELECT id FROM test WHERE query_string(['address', 'notes' 3], 'query')")); - assertNotNull(parser.parse( - "SELECT id FROM test WHERE query_string(['address' ^ .3, 'notes' 3], 'query')")); - - assertNotNull(parser.parse( - "SELECT id FROM test WHERE" - + " query_string([\"Tags\" ^ 1.5, Title, `Body` 4.2], 'query')")); - assertNotNull(parser.parse( - "SELECT id FROM test WHERE" - + " query_string([\"Tags\" ^ 1.5, Title, `Body` 4.2], 'query', analyzer=keyword," - + "operator='AND', tie_breaker=0.3, type = \"most_fields\", fuzziness = 4)")); - } + assertNotNull(parser.parse("SELECT id FROM test WHERE query_string(['*'], 'query')")); + assertNotNull(parser.parse("SELECT id FROM test WHERE query_string(['address'], 'query')")); + assertNotNull(parser.parse("SELECT id FROM test WHERE query_string(['add*'], 'query')")); + assertNotNull(parser.parse("SELECT id FROM test WHERE query_string(['*ess'], 'query')")); + assertNotNull( + parser.parse("SELECT id FROM test WHERE query_string(['address', 'notes'], 'query')")); + assertNotNull(parser.parse("SELECT id FROM test WHERE query_string([\"*\"], 'query')")); + assertNotNull(parser.parse("SELECT id FROM test WHERE query_string([\"address\"], 'query')")); + assertNotNull(parser.parse("SELECT id FROM test WHERE query_string([\"ad*\"], 'query')")); + assertNotNull(parser.parse("SELECT id FROM test WHERE query_string([\"*s\"], 'query')")); + assertNotNull( + parser.parse("SELECT id FROM test WHERE query_string([\"address\", \"notes\"], 'query')")); + assertNotNull(parser.parse("SELECT id FROM test WHERE query_string([`*`], 'query')")); + assertNotNull(parser.parse("SELECT id FROM test WHERE query_string([`address`], 'query')")); + assertNotNull(parser.parse("SELECT id FROM test WHERE query_string([`ad*`], 'query')")); + assertNotNull(parser.parse("SELECT id FROM test WHERE query_string([`*ss`], 'query')")); + assertNotNull( + parser.parse("SELECT id FROM test WHERE query_string([`address`, `notes`], 'query')")); + assertNotNull(parser.parse("SELECT id FROM test WHERE query_string([address], 'query')")); + assertNotNull(parser.parse("SELECT id FROM test WHERE query_string([addr*], 'query')")); + assertNotNull(parser.parse("SELECT id FROM test WHERE query_string([*ss], 'query')")); + assertNotNull( + parser.parse("SELECT id FROM test WHERE query_string([address, notes], 'query')")); + assertNotNull( + parser.parse( + "SELECT id FROM test WHERE" + + " query_string(['address' ^ 1.0, 'notes' ^ 2.2], 'query')")); + assertNotNull( + parser.parse( + "SELECT id FROM test WHERE query_string(['address' ^ 1.1, 'notes'], 'query')")); + assertNotNull( + parser.parse( + "SELECT id FROM test WHERE query_string(['address', 'notes' ^ 1.5], 'query')")); + assertNotNull( + parser.parse("SELECT id FROM test WHERE query_string(['address', 'notes' 3], 'query')")); + assertNotNull( + parser.parse( + "SELECT id FROM test WHERE query_string(['address' ^ .3, 'notes' 3], 'query')")); + + assertNotNull( + parser.parse( + "SELECT id FROM test WHERE" + + " query_string([\"Tags\" ^ 1.5, Title, `Body` 4.2], 'query')")); + assertNotNull( + parser.parse( + "SELECT id FROM test WHERE" + + " query_string([\"Tags\" ^ 1.5, Title, `Body` 4.2], 'query', analyzer=keyword," + + "operator='AND', tie_breaker=0.3, type = \"most_fields\", fuzziness = 4)")); + } @Test public void can_parse_query_relevance_function() { - assertNotNull(parser.parse( - "SELECT id FROM test WHERE query('address:query')")); - assertNotNull(parser.parse( - "SELECT id FROM test WHERE query('address:query OR notes:query')")); - assertNotNull(parser.parse( - "SELECT id FROM test WHERE query(\"address:query\")")); - assertNotNull(parser.parse( - "SELECT id FROM test WHERE query(\"address:query OR notes:query\")")); - assertNotNull(parser.parse( - "SELECT id FROM test WHERE query(`address:query`)")); - assertNotNull(parser.parse( - "SELECT id FROM test WHERE query(`address:query OR notes:query`)")); - assertNotNull(parser.parse( - "SELECT id FROM test WHERE query('*:query')")); - assertNotNull(parser.parse( - "SELECT id FROM test WHERE query(\"*:query\")")); - assertNotNull(parser.parse( - "SELECT id FROM test WHERE query(`*:query`)")); - assertNotNull(parser.parse( - "SELECT id FROM test WHERE query('address:*uery OR notes:?uery')")); - assertNotNull(parser.parse( - "SELECT id FROM test WHERE query(\"address:*uery OR notes:?uery\")")); - assertNotNull(parser.parse( - "SELECT id FROM test WHERE query(`address:*uery OR notes:?uery`)")); - assertNotNull(parser.parse( - "SELECT id FROM test WHERE query('address:qu*ry OR notes:qu?ry')")); - assertNotNull(parser.parse( - "SELECT id FROM test WHERE query(\"address:qu*ry OR notes:qu?ry\")")); - assertNotNull(parser.parse( - "SELECT id FROM test WHERE query(`address:qu*ry OR notes:qu?ry`)")); - assertNotNull(parser.parse( - "SELECT id FROM test WHERE query('address:query notes:query')")); - assertNotNull(parser.parse( - "SELECT id FROM test WHERE query(\"address:query notes:query\")")); - assertNotNull(parser.parse( + assertNotNull(parser.parse("SELECT id FROM test WHERE query('address:query')")); + assertNotNull(parser.parse("SELECT id FROM test WHERE query('address:query OR notes:query')")); + assertNotNull(parser.parse("SELECT id FROM test WHERE query(\"address:query\")")); + assertNotNull( + parser.parse("SELECT id FROM test WHERE query(\"address:query OR notes:query\")")); + assertNotNull(parser.parse("SELECT id FROM test WHERE query(`address:query`)")); + assertNotNull(parser.parse("SELECT id FROM test WHERE query(`address:query OR notes:query`)")); + assertNotNull(parser.parse("SELECT id FROM test WHERE query('*:query')")); + assertNotNull(parser.parse("SELECT id FROM test WHERE query(\"*:query\")")); + assertNotNull(parser.parse("SELECT id FROM test WHERE query(`*:query`)")); + assertNotNull(parser.parse("SELECT id FROM test WHERE query('address:*uery OR notes:?uery')")); + assertNotNull( + parser.parse("SELECT id FROM test WHERE query(\"address:*uery OR notes:?uery\")")); + assertNotNull(parser.parse("SELECT id FROM test WHERE query(`address:*uery OR notes:?uery`)")); + assertNotNull(parser.parse("SELECT id FROM test WHERE query('address:qu*ry OR notes:qu?ry')")); + assertNotNull( + parser.parse("SELECT id FROM test WHERE query(\"address:qu*ry OR notes:qu?ry\")")); + assertNotNull(parser.parse("SELECT id FROM test WHERE query(`address:qu*ry OR notes:qu?ry`)")); + assertNotNull(parser.parse("SELECT id FROM test WHERE query('address:query notes:query')")); + assertNotNull(parser.parse("SELECT id FROM test WHERE query(\"address:query notes:query\")")); + assertNotNull( + parser.parse( "SELECT id FROM test WHERE " - + "query(\"Body:\'taste beer\' Tags:\'taste beer\' Title:\'taste beer\'\")")); + + "query(\"Body:\'taste beer\' Tags:\'taste beer\' Title:\'taste beer\'\")")); } - @Test public void can_parse_match_relevance_function() { assertNotNull(parser.parse("SELECT * FROM test WHERE match(column, \"this is a test\")")); @@ -552,19 +527,18 @@ public void can_parse_match_relevance_function() { public void can_parse_matchquery_relevance_function() { assertNotNull(parser.parse("SELECT * FROM test WHERE matchquery(column, \"this is a test\")")); assertNotNull(parser.parse("SELECT * FROM test WHERE matchquery(column, 'this is a test')")); - assertNotNull(parser.parse( - "SELECT * FROM test WHERE matchquery(`column`, \"this is a test\")")); + assertNotNull( + parser.parse("SELECT * FROM test WHERE matchquery(`column`, \"this is a test\")")); assertNotNull(parser.parse("SELECT * FROM test WHERE matchquery(`column`, 'this is a test')")); assertNotNull(parser.parse("SELECT * FROM test WHERE matchquery(column, 100500)")); } @Test public void can_parse_match_query_relevance_function() { - assertNotNull(parser.parse( - "SELECT * FROM test WHERE match_query(column, \"this is a test\")")); + assertNotNull(parser.parse("SELECT * FROM test WHERE match_query(column, \"this is a test\")")); assertNotNull(parser.parse("SELECT * FROM test WHERE match_query(column, 'this is a test')")); - assertNotNull(parser.parse( - "SELECT * FROM test WHERE match_query(`column`, \"this is a test\")")); + assertNotNull( + parser.parse("SELECT * FROM test WHERE match_query(`column`, \"this is a test\")")); assertNotNull(parser.parse("SELECT * FROM test WHERE match_query(`column`, 'this is a test')")); assertNotNull(parser.parse("SELECT * FROM test WHERE match_query(column, 100500)")); } @@ -572,21 +546,24 @@ public void can_parse_match_query_relevance_function() { @Test public void can_parse_match_phrase_relevance_function() { assertNotNull( - parser.parse("SELECT * FROM test WHERE match_phrase(column, \"this is a test\")")); + parser.parse("SELECT * FROM test WHERE match_phrase(column, \"this is a test\")")); assertNotNull(parser.parse("SELECT * FROM test WHERE match_phrase(column, 'this is a test')")); assertNotNull( - parser.parse("SELECT * FROM test WHERE match_phrase(`column`, \"this is a test\")")); + parser.parse("SELECT * FROM test WHERE match_phrase(`column`, \"this is a test\")")); assertNotNull( - parser.parse("SELECT * FROM test WHERE match_phrase(`column`, 'this is a test')")); + parser.parse("SELECT * FROM test WHERE match_phrase(`column`, 'this is a test')")); assertNotNull(parser.parse("SELECT * FROM test WHERE match_phrase(column, 100500)")); } @Test public void can_parse_minute_of_day_function() { assertNotNull(parser.parse("SELECT minute_of_day(\"12:23:34\");")); - assertNotNull(parser.parse("SELECT minute_of_day('12:23:34');"));; - assertNotNull(parser.parse("SELECT minute_of_day(\"2022-12-14 12:23:34\");"));; - assertNotNull(parser.parse("SELECT minute_of_day('2022-12-14 12:23:34');"));; + assertNotNull(parser.parse("SELECT minute_of_day('12:23:34');")); + ; + assertNotNull(parser.parse("SELECT minute_of_day(\"2022-12-14 12:23:34\");")); + ; + assertNotNull(parser.parse("SELECT minute_of_day('2022-12-14 12:23:34');")); + ; } @Test @@ -631,35 +608,20 @@ public void can_parse_wildcard_query_relevance_function() { assertNotNull( parser.parse("SELECT * FROM test WHERE wildcard_query(`column`, 'this is a test*')")); assertNotNull( - parser.parse("SELECT * FROM test WHERE wildcard_query(`column`, 'this is a test*', " - + "boost=1.5, case_insensitive=true, rewrite=\"scoring_boolean\")")); + parser.parse( + "SELECT * FROM test WHERE wildcard_query(`column`, 'this is a test*', " + + "boost=1.5, case_insensitive=true, rewrite=\"scoring_boolean\")")); } @Test public void can_parse_nested_function() { - assertNotNull( - parser.parse("SELECT NESTED(PATH.INNER_FIELD) FROM TEST")); - assertNotNull( - parser.parse("SELECT NESTED('PATH.INNER_FIELD') FROM TEST")); - assertNotNull( - parser.parse("SELECT SUM(NESTED(PATH.INNER_FIELD)) FROM TEST")); - assertNotNull( - parser.parse("SELECT NESTED(PATH.INNER_FIELD, PATH) FROM TEST")); - assertNotNull( - parser.parse( - "SELECT * FROM TEST WHERE NESTED(PATH.INNER_FIELDS) = 'A'" - ) - ); - assertNotNull( - parser.parse( - "SELECT * FROM TEST WHERE NESTED(PATH.INNER_FIELDS, PATH) = 'A'" - ) - ); - assertNotNull( - parser.parse( - "SELECT FIELD FROM TEST ORDER BY nested(PATH.INNER_FIELD, PATH)" - ) - ); + assertNotNull(parser.parse("SELECT NESTED(PATH.INNER_FIELD) FROM TEST")); + assertNotNull(parser.parse("SELECT NESTED('PATH.INNER_FIELD') FROM TEST")); + assertNotNull(parser.parse("SELECT SUM(NESTED(PATH.INNER_FIELD)) FROM TEST")); + assertNotNull(parser.parse("SELECT NESTED(PATH.INNER_FIELD, PATH) FROM TEST")); + assertNotNull(parser.parse("SELECT * FROM TEST WHERE NESTED(PATH.INNER_FIELDS) = 'A'")); + assertNotNull(parser.parse("SELECT * FROM TEST WHERE NESTED(PATH.INNER_FIELDS, PATH) = 'A'")); + assertNotNull(parser.parse("SELECT FIELD FROM TEST ORDER BY nested(PATH.INNER_FIELD, PATH)")); } @Test @@ -671,68 +633,69 @@ public void can_parse_yearweek_function() { @Test public void describe_request_accepts_only_quoted_string_literals() { assertAll( - () -> assertThrows(SyntaxCheckException.class, - () -> parser.parse("DESCRIBE TABLES LIKE bank")), - () -> assertThrows(SyntaxCheckException.class, - () -> parser.parse("DESCRIBE TABLES LIKE %bank%")), - () -> assertThrows(SyntaxCheckException.class, - () -> parser.parse("DESCRIBE TABLES LIKE `bank`")), - () -> assertThrows(SyntaxCheckException.class, - () -> parser.parse("DESCRIBE TABLES LIKE %bank% COLUMNS LIKE %status%")), - () -> assertThrows(SyntaxCheckException.class, - () -> parser.parse("DESCRIBE TABLES LIKE 'bank' COLUMNS LIKE status")), + () -> + assertThrows( + SyntaxCheckException.class, () -> parser.parse("DESCRIBE TABLES LIKE bank")), + () -> + assertThrows( + SyntaxCheckException.class, () -> parser.parse("DESCRIBE TABLES LIKE %bank%")), + () -> + assertThrows( + SyntaxCheckException.class, () -> parser.parse("DESCRIBE TABLES LIKE `bank`")), + () -> + assertThrows( + SyntaxCheckException.class, + () -> parser.parse("DESCRIBE TABLES LIKE %bank% COLUMNS LIKE %status%")), + () -> + assertThrows( + SyntaxCheckException.class, + () -> parser.parse("DESCRIBE TABLES LIKE 'bank' COLUMNS LIKE status")), () -> assertNotNull(parser.parse("DESCRIBE TABLES LIKE 'bank' COLUMNS LIKE \"status\"")), - () -> assertNotNull(parser.parse("DESCRIBE TABLES LIKE \"bank\" COLUMNS LIKE 'status'")) - ); + () -> assertNotNull(parser.parse("DESCRIBE TABLES LIKE \"bank\" COLUMNS LIKE 'status'"))); } @Test public void show_request_accepts_only_quoted_string_literals() { assertAll( - () -> assertThrows(SyntaxCheckException.class, - () -> parser.parse("SHOW TABLES LIKE bank")), - () -> assertThrows(SyntaxCheckException.class, - () -> parser.parse("SHOW TABLES LIKE %bank%")), - () -> assertThrows(SyntaxCheckException.class, - () -> parser.parse("SHOW TABLES LIKE `bank`")), + () -> assertThrows(SyntaxCheckException.class, () -> parser.parse("SHOW TABLES LIKE bank")), + () -> + assertThrows(SyntaxCheckException.class, () -> parser.parse("SHOW TABLES LIKE %bank%")), + () -> + assertThrows(SyntaxCheckException.class, () -> parser.parse("SHOW TABLES LIKE `bank`")), () -> assertNotNull(parser.parse("SHOW TABLES LIKE 'bank'")), - () -> assertNotNull(parser.parse("SHOW TABLES LIKE \"bank\"")) - ); + () -> assertNotNull(parser.parse("SHOW TABLES LIKE \"bank\""))); } @ParameterizedTest @MethodSource({ - "matchPhraseComplexQueries", - "matchPhraseGeneratedQueries", - "generateMatchPhraseQueries", - "matchPhraseQueryComplexQueries" + "matchPhraseComplexQueries", + "matchPhraseGeneratedQueries", + "generateMatchPhraseQueries", + "matchPhraseQueryComplexQueries" }) public void canParseComplexMatchPhraseArgsTest(String query) { assertNotNull(parser.parse(query)); } @ParameterizedTest - @MethodSource({ - "generateMatchPhrasePrefixQueries" - }) + @MethodSource({"generateMatchPhrasePrefixQueries"}) public void canParseComplexMatchPhrasePrefixQueries(String query) { assertNotNull(parser.parse(query)); } private static Stream matchPhraseComplexQueries() { return Stream.of( - "SELECT * FROM t WHERE match_phrase(c, 3)", - "SELECT * FROM t WHERE match_phrase(c, 3, fuzziness=AUTO)", - "SELECT * FROM t WHERE match_phrase(c, 3, zero_terms_query=\"all\")", - "SELECT * FROM t WHERE match_phrase(c, 3, lenient=true)", - "SELECT * FROM t WHERE match_phrase(c, 3, lenient='true')", - "SELECT * FROM t WHERE match_phrase(c, 3, operator=xor)", - "SELECT * FROM t WHERE match_phrase(c, 3, cutoff_frequency=0.04)", - "SELECT * FROM t WHERE match_phrase(c, 3, cutoff_frequency=0.04, analyzer = english, " - + "prefix_length=34, fuzziness='auto', minimum_should_match='2<-25% 9<-3')", - "SELECT * FROM t WHERE match_phrase(c, 3, minimum_should_match='2<-25% 9<-3')", - "SELECT * FROM t WHERE match_phrase(c, 3, operator='AUTO')" - ); + "SELECT * FROM t WHERE match_phrase(c, 3)", + "SELECT * FROM t WHERE match_phrase(c, 3, fuzziness=AUTO)", + "SELECT * FROM t WHERE match_phrase(c, 3, zero_terms_query=\"all\")", + "SELECT * FROM t WHERE match_phrase(c, 3, lenient=true)", + "SELECT * FROM t WHERE match_phrase(c, 3, lenient='true')", + "SELECT * FROM t WHERE match_phrase(c, 3, operator=xor)", + "SELECT * FROM t WHERE match_phrase(c, 3, cutoff_frequency=0.04)", + "SELECT * FROM t WHERE match_phrase(c, 3, cutoff_frequency=0.04, analyzer = english, " + + "prefix_length=34, fuzziness='auto', minimum_should_match='2<-25% 9<-3')", + "SELECT * FROM t WHERE match_phrase(c, 3, minimum_should_match='2<-25% 9<-3')", + "SELECT * FROM t WHERE match_phrase(c, 3, operator='AUTO')"); } @Test @@ -771,50 +734,51 @@ private static Stream matchPhraseQueryComplexQueries() { "SELECT * FROM t WHERE matchphrasequery(c, 3, cutoff_frequency=0.04, analyzer = english, " + "prefix_length=34, fuzziness='auto', minimum_should_match='2<-25% 9<-3')", "SELECT * FROM t WHERE matchphrasequery(c, 3, minimum_should_match='2<-25% 9<-3')", - "SELECT * FROM t WHERE matchphrasequery(c, 3, operator='AUTO')" - ); + "SELECT * FROM t WHERE matchphrasequery(c, 3, operator='AUTO')"); } private static Stream matchPhraseGeneratedQueries() { var matchArgs = new HashMap(); - matchArgs.put("fuzziness", new String[]{ "AUTO", "AUTO:1,5", "1" }); - matchArgs.put("fuzzy_transpositions", new Boolean[]{ true, false }); - matchArgs.put("operator", new String[]{ "and", "or" }); - matchArgs.put("minimum_should_match", - new String[]{ "3", "-2", "75%", "-25%", "3<90%", "2<-25% 9<-3" }); - matchArgs.put("analyzer", new String[]{ "standard", "stop", "english" }); - matchArgs.put("zero_terms_query", new String[]{ "none", "all" }); - matchArgs.put("lenient", new Boolean[]{ true, false }); + matchArgs.put("fuzziness", new String[] {"AUTO", "AUTO:1,5", "1"}); + matchArgs.put("fuzzy_transpositions", new Boolean[] {true, false}); + matchArgs.put("operator", new String[] {"and", "or"}); + matchArgs.put( + "minimum_should_match", new String[] {"3", "-2", "75%", "-25%", "3<90%", "2<-25% 9<-3"}); + matchArgs.put("analyzer", new String[] {"standard", "stop", "english"}); + matchArgs.put("zero_terms_query", new String[] {"none", "all"}); + matchArgs.put("lenient", new Boolean[] {true, false}); // deprecated - matchArgs.put("cutoff_frequency", new Double[]{ .0, 0.001, 1., 42. }); - matchArgs.put("prefix_length", new Integer[]{ 0, 2, 5 }); - matchArgs.put("max_expansions", new Integer[]{ 0, 5, 20 }); - matchArgs.put("boost", new Double[]{ .5, 1., 2.3 }); + matchArgs.put("cutoff_frequency", new Double[] {.0, 0.001, 1., 42.}); + matchArgs.put("prefix_length", new Integer[] {0, 2, 5}); + matchArgs.put("max_expansions", new Integer[] {0, 5, 20}); + matchArgs.put("boost", new Double[] {.5, 1., 2.3}); return generateQueries("match", matchArgs); } private static Stream generateMatchPhraseQueries() { var matchPhraseArgs = new HashMap(); - matchPhraseArgs.put("analyzer", new String[]{ "standard", "stop", "english" }); - matchPhraseArgs.put("max_expansions", new Integer[]{ 0, 5, 20 }); - matchPhraseArgs.put("slop", new Integer[]{ 0, 1, 2 }); + matchPhraseArgs.put("analyzer", new String[] {"standard", "stop", "english"}); + matchPhraseArgs.put("max_expansions", new Integer[] {0, 5, 20}); + matchPhraseArgs.put("slop", new Integer[] {0, 1, 2}); return generateQueries("match_phrase", matchPhraseArgs); } private static Stream generateMatchPhrasePrefixQueries() { - return generateQueries("match_phrase_prefix", ImmutableMap.builder() - .put("analyzer", new String[] {"standard", "stop", "english"}) - .put("slop", new Integer[] {0, 1, 2}) - .put("max_expansions", new Integer[] {0, 3, 10}) - .put("zero_terms_query", new String[] {"NONE", "ALL", "NULL"}) - .put("boost", new Float[] {-0.5f, 1.0f, 1.2f}) - .build()); - } - - private static Stream generateQueries(String function, - Map functionArgs) { + return generateQueries( + "match_phrase_prefix", + ImmutableMap.builder() + .put("analyzer", new String[] {"standard", "stop", "english"}) + .put("slop", new Integer[] {0, 1, 2}) + .put("max_expansions", new Integer[] {0, 3, 10}) + .put("zero_terms_query", new String[] {"NONE", "ALL", "NULL"}) + .put("boost", new Float[] {-0.5f, 1.0f, 1.2f}) + .build()); + } + + private static Stream generateQueries( + String function, Map functionArgs) { var rand = new Random(0); class QueryGenerator implements Iterator { @@ -822,7 +786,7 @@ class QueryGenerator implements Iterator { private int currentQuery = 0; private String randomIdentifier() { - return RandomStringUtils.random(10, 0, 0,true, false, null, rand); + return RandomStringUtils.random(10, 0, 0, true, false, null, rand); } @Override @@ -836,16 +800,17 @@ public String next() { currentQuery += 1; StringBuilder query = new StringBuilder(); - query.append(String.format("SELECT * FROM test WHERE %s(%s, %s", function, - randomIdentifier(), - randomIdentifier())); + query.append( + String.format( + "SELECT * FROM test WHERE %s(%s, %s", + function, randomIdentifier(), randomIdentifier())); var args = new ArrayList(); for (var pair : functionArgs.entrySet()) { if (rand.nextBoolean()) { var arg = new StringBuilder(); arg.append(rand.nextBoolean() ? "," : ", "); - arg.append(rand.nextBoolean() ? pair.getKey().toLowerCase() - : pair.getKey().toUpperCase()); + arg.append( + rand.nextBoolean() ? pair.getKey().toLowerCase() : pair.getKey().toUpperCase()); arg.append(rand.nextBoolean() ? "=" : " = "); if (pair.getValue() instanceof String[] || rand.nextBoolean()) { var quoteSymbol = rand.nextBoolean() ? '\'' : '"'; diff --git a/sql/src/test/java/org/opensearch/sql/sql/domain/SQLQueryRequestTest.java b/sql/src/test/java/org/opensearch/sql/sql/domain/SQLQueryRequestTest.java index 1ffa4f0fa8..2b64b13b35 100644 --- a/sql/src/test/java/org/opensearch/sql/sql/domain/SQLQueryRequestTest.java +++ b/sql/src/test/java/org/opensearch/sql/sql/domain/SQLQueryRequestTest.java @@ -3,7 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ - package org.opensearch.sql.sql.domain; import static org.junit.jupiter.api.Assertions.assertAll; @@ -32,21 +31,15 @@ public void should_support_query() { @Test public void should_support_query_with_JDBC_format() { - SQLQueryRequest request = SQLQueryRequestBuilder.request("SELECT 1") - .format("jdbc") - .build(); + SQLQueryRequest request = SQLQueryRequestBuilder.request("SELECT 1").format("jdbc").build(); assertAll( - () -> assertTrue(request.isSupported()), - () -> assertEquals(request.format(), Format.JDBC) - ); + () -> assertTrue(request.isSupported()), () -> assertEquals(request.format(), Format.JDBC)); } @Test public void should_support_query_with_query_field_only() { SQLQueryRequest request = - SQLQueryRequestBuilder.request("SELECT 1") - .jsonContent("{\"query\": \"SELECT 1\"}") - .build(); + SQLQueryRequestBuilder.request("SELECT 1").jsonContent("{\"query\": \"SELECT 1\"}").build(); assertTrue(request.isSupported()); } @@ -57,21 +50,16 @@ public void should_support_query_with_parameters() { .jsonContent("{\"query\": \"SELECT 1\", \"parameters\":[]}") .build(); SQLQueryRequest requestWithParams = - SQLQueryRequestBuilder.request("SELECT 1") - .params(Map.of("one", "two")) - .build(); + SQLQueryRequestBuilder.request("SELECT 1").params(Map.of("one", "two")).build(); assertAll( () -> assertTrue(requestWithContent.isSupported()), - () -> assertTrue(requestWithParams.isSupported()) - ); + () -> assertTrue(requestWithParams.isSupported())); } @Test public void should_support_query_without_parameters() { SQLQueryRequest requestWithNoParams = - SQLQueryRequestBuilder.request("SELECT 1") - .params(Map.of()) - .build(); + SQLQueryRequestBuilder.request("SELECT 1").params(Map.of()).build(); assertTrue(requestWithNoParams.isSupported()); } @@ -79,8 +67,8 @@ public void should_support_query_without_parameters() { public void should_support_query_with_zero_fetch_size() { SQLQueryRequest request = SQLQueryRequestBuilder.request("SELECT 1") - .jsonContent("{\"query\": \"SELECT 1\", \"fetch_size\": 0}") - .build(); + .jsonContent("{\"query\": \"SELECT 1\", \"fetch_size\": 0}") + .build(); assertTrue(request.isSupported()); } @@ -96,52 +84,37 @@ public void should_support_query_with_parameters_and_zero_fetch_size() { @Test public void should_support_explain() { SQLQueryRequest explainRequest = - SQLQueryRequestBuilder.request("SELECT 1") - .path("_plugins/_sql/_explain") - .build(); + SQLQueryRequestBuilder.request("SELECT 1").path("_plugins/_sql/_explain").build(); assertAll( () -> assertTrue(explainRequest.isExplainRequest()), - () -> assertTrue(explainRequest.isSupported()) - ); + () -> assertTrue(explainRequest.isSupported())); } @Test public void should_support_cursor_request() { SQLQueryRequest fetchSizeRequest = SQLQueryRequestBuilder.request("SELECT 1") - .jsonContent("{\"query\": \"SELECT 1\", \"fetch_size\": 5}") - .build(); + .jsonContent("{\"query\": \"SELECT 1\", \"fetch_size\": 5}") + .build(); SQLQueryRequest cursorRequest = - SQLQueryRequestBuilder.request(null) - .cursor("abcdefgh...") - .build(); + SQLQueryRequestBuilder.request(null).cursor("abcdefgh...").build(); assertAll( () -> assertTrue(fetchSizeRequest.isSupported()), - () -> assertTrue(cursorRequest.isSupported()) - ); + () -> assertTrue(cursorRequest.isSupported())); } @Test public void should_support_cursor_close_request() { SQLQueryRequest closeRequest = - SQLQueryRequestBuilder.request(null) - .cursor("pewpew") - .path("_plugins/_sql/close") - .build(); + SQLQueryRequestBuilder.request(null).cursor("pewpew").path("_plugins/_sql/close").build(); SQLQueryRequest emptyCloseRequest = - SQLQueryRequestBuilder.request(null) - .cursor("") - .path("_plugins/_sql/close") - .build(); + SQLQueryRequestBuilder.request(null).cursor("").path("_plugins/_sql/close").build(); - SQLQueryRequest pagingRequest = - SQLQueryRequestBuilder.request(null) - .cursor("pewpew") - .build(); + SQLQueryRequest pagingRequest = SQLQueryRequestBuilder.request(null).cursor("pewpew").build(); assertAll( () -> assertTrue(closeRequest.isSupported()), @@ -149,71 +122,52 @@ public void should_support_cursor_close_request() { () -> assertTrue(pagingRequest.isSupported()), () -> assertFalse(pagingRequest.isCursorCloseRequest()), () -> assertFalse(emptyCloseRequest.isSupported()), - () -> assertTrue(emptyCloseRequest.isCursorCloseRequest()) - ); + () -> assertTrue(emptyCloseRequest.isCursorCloseRequest())); } @Test public void should_not_support_request_with_empty_cursor() { SQLQueryRequest requestWithEmptyCursor = - SQLQueryRequestBuilder.request(null) - .cursor("") - .build(); + SQLQueryRequestBuilder.request(null).cursor("").build(); SQLQueryRequest requestWithNullCursor = - SQLQueryRequestBuilder.request(null) - .cursor(null) - .build(); + SQLQueryRequestBuilder.request(null).cursor(null).build(); assertAll( () -> assertFalse(requestWithEmptyCursor.isSupported()), - () -> assertFalse(requestWithNullCursor.isSupported()) - ); + () -> assertFalse(requestWithNullCursor.isSupported())); } @Test public void should_not_support_request_with_unknown_field() { SQLQueryRequest request = - SQLQueryRequestBuilder.request("SELECT 1") - .jsonContent("{\"pewpew\": 42}") - .build(); + SQLQueryRequestBuilder.request("SELECT 1").jsonContent("{\"pewpew\": 42}").build(); assertFalse(request.isSupported()); } @Test public void should_not_support_request_with_cursor_and_something_else() { SQLQueryRequest requestWithQuery = - SQLQueryRequestBuilder.request("SELECT 1") - .cursor("n:12356") - .build(); + SQLQueryRequestBuilder.request("SELECT 1").cursor("n:12356").build(); SQLQueryRequest requestWithParams = - SQLQueryRequestBuilder.request(null) - .cursor("n:12356") - .params(Map.of("one", "two")) - .build(); + SQLQueryRequestBuilder.request(null).cursor("n:12356").params(Map.of("one", "two")).build(); SQLQueryRequest requestWithParamsWithFormat = SQLQueryRequestBuilder.request(null) - .cursor("n:12356") - .params(Map.of("format", "jdbc")) - .build(); + .cursor("n:12356") + .params(Map.of("format", "jdbc")) + .build(); SQLQueryRequest requestWithParamsWithFormatAnd = SQLQueryRequestBuilder.request(null) - .cursor("n:12356") - .params(Map.of("format", "jdbc", "something", "else")) - .build(); + .cursor("n:12356") + .params(Map.of("format", "jdbc", "something", "else")) + .build(); SQLQueryRequest requestWithFetchSize = SQLQueryRequestBuilder.request(null) - .cursor("n:12356") - .jsonContent("{\"fetch_size\": 5}") - .build(); + .cursor("n:12356") + .jsonContent("{\"fetch_size\": 5}") + .build(); SQLQueryRequest requestWithNoParams = - SQLQueryRequestBuilder.request(null) - .cursor("n:12356") - .params(Map.of()) - .build(); + SQLQueryRequestBuilder.request(null).cursor("n:12356").params(Map.of()).build(); SQLQueryRequest requestWithNoContent = - SQLQueryRequestBuilder.request(null) - .cursor("n:12356") - .jsonContent("{}") - .build(); + SQLQueryRequestBuilder.request(null).cursor("n:12356").jsonContent("{}").build(); assertAll( () -> assertFalse(requestWithQuery.isSupported()), () -> assertFalse(requestWithParams.isSupported()), @@ -221,8 +175,7 @@ public void should_not_support_request_with_cursor_and_something_else() { () -> assertTrue(requestWithNoParams.isSupported()), () -> assertTrue(requestWithParamsWithFormat.isSupported()), () -> assertFalse(requestWithParamsWithFormatAnd.isSupported()), - () -> assertTrue(requestWithNoContent.isSupported()) - ); + () -> assertTrue(requestWithNoContent.isSupported())); } @Test @@ -234,15 +187,11 @@ public void should_use_JDBC_format_by_default() { @Test public void should_support_CSV_format_and_sanitize() { - SQLQueryRequest csvRequest = - SQLQueryRequestBuilder.request("SELECT 1") - .format("csv") - .build(); + SQLQueryRequest csvRequest = SQLQueryRequestBuilder.request("SELECT 1").format("csv").build(); assertAll( () -> assertTrue(csvRequest.isSupported()), () -> assertEquals(csvRequest.format(), Format.CSV), - () -> assertTrue(csvRequest.sanitize()) - ); + () -> assertTrue(csvRequest.sanitize())); } @Test @@ -252,36 +201,28 @@ public void should_skip_sanitize_if_set_false() { SQLQueryRequest csvRequest = SQLQueryRequestBuilder.request("SELECT 1").params(params).build(); assertAll( () -> assertEquals(csvRequest.format(), Format.CSV), - () -> assertFalse(csvRequest.sanitize()) - ); + () -> assertFalse(csvRequest.sanitize())); } @Test public void should_not_support_other_format() { - SQLQueryRequest csvRequest = - SQLQueryRequestBuilder.request("SELECT 1") - .format("other") - .build(); + SQLQueryRequest csvRequest = SQLQueryRequestBuilder.request("SELECT 1").format("other").build(); assertAll( () -> assertFalse(csvRequest.isSupported()), - () -> assertEquals("response in other format is not supported.", - assertThrows(IllegalArgumentException.class, csvRequest::format).getMessage()) - ); + () -> + assertEquals( + "response in other format is not supported.", + assertThrows(IllegalArgumentException.class, csvRequest::format).getMessage())); } @Test public void should_support_raw_format() { - SQLQueryRequest csvRequest = - SQLQueryRequestBuilder.request("SELECT 1") - .format("raw") - .build(); + SQLQueryRequest csvRequest = SQLQueryRequestBuilder.request("SELECT 1").format("raw").build(); assertTrue(csvRequest.isSupported()); } - /** - * SQL query request build helper to improve test data setup readability. - */ + /** SQL query request build helper to improve test data setup readability. */ private static class SQLQueryRequestBuilder { private String jsonContent; private String query; @@ -325,9 +266,8 @@ SQLQueryRequest build() { if (format != null) { params.put("format", format); } - return new SQLQueryRequest(jsonContent == null ? null : new JSONObject(jsonContent), - query, path, params, cursor); + return new SQLQueryRequest( + jsonContent == null ? null : new JSONObject(jsonContent), query, path, params, cursor); } } - } diff --git a/sql/src/test/java/org/opensearch/sql/sql/parser/AnonymizerListenerTest.java b/sql/src/test/java/org/opensearch/sql/sql/parser/AnonymizerListenerTest.java index 59d723e3a2..4d2addf3d3 100644 --- a/sql/src/test/java/org/opensearch/sql/sql/parser/AnonymizerListenerTest.java +++ b/sql/src/test/java/org/opensearch/sql/sql/parser/AnonymizerListenerTest.java @@ -3,7 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ - package org.opensearch.sql.sql.parser; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -23,6 +22,7 @@ public class AnonymizerListenerTest { /** * Helper function to parse SQl queries for testing purposes. + * * @param query SQL query to be anonymized. */ private void parse(String query) { @@ -36,8 +36,9 @@ private void parse(String query) { @Test public void queriesShouldHaveAnonymousFieldAndIndex() { String query = "SELECT ABS(balance) FROM accounts WHERE age > 30 GROUP BY ABS(balance)"; - String expectedQuery = "( SELECT ABS ( identifier ) FROM table " - + "WHERE identifier > number GROUP BY ABS ( identifier ) )"; + String expectedQuery = + "( SELECT ABS ( identifier ) FROM table " + + "WHERE identifier > number GROUP BY ABS ( identifier ) )"; parse(query); assertEquals(expectedQuery, anonymizerListener.getAnonymizedQueryString()); } @@ -92,12 +93,13 @@ public void queriesWithAggregatesShouldAnonymizeSensitiveData() { @Test public void queriesWithSubqueriesShouldAnonymizeSensitiveData() { - String query = "SELECT a.f, a.l, a.a FROM " - + "(SELECT firstname AS f, lastname AS l, age AS a FROM accounts WHERE age > 30) a"; + String query = + "SELECT a.f, a.l, a.a FROM " + + "(SELECT firstname AS f, lastname AS l, age AS a FROM accounts WHERE age > 30) a"; String expectedQuery = - "( SELECT identifier.identifier, identifier.identifier, identifier.identifier FROM " - + "( SELECT identifier AS identifier, identifier AS identifier, identifier AS identifier " - + "FROM table WHERE identifier > number ) identifier )"; + "( SELECT identifier.identifier, identifier.identifier, identifier.identifier FROM ( SELECT" + + " identifier AS identifier, identifier AS identifier, identifier AS identifier FROM" + + " table WHERE identifier > number ) identifier )"; parse(query); assertEquals(expectedQuery, anonymizerListener.getAnonymizedQueryString()); } @@ -121,8 +123,9 @@ public void queriesWithOrderByShouldAnonymizeSensitiveData() { @Test public void queriesWithHavingShouldAnonymizeSensitiveData() { String query = "SELECT SUM(balance) FROM accounts GROUP BY lastname HAVING COUNT(balance) > 2"; - String expectedQuery = "( SELECT SUM ( identifier ) FROM table " - + "GROUP BY identifier HAVING COUNT ( identifier ) > number )"; + String expectedQuery = + "( SELECT SUM ( identifier ) FROM table " + + "GROUP BY identifier HAVING COUNT ( identifier ) > number )"; parse(query); assertEquals(expectedQuery, anonymizerListener.getAnonymizedQueryString()); } @@ -130,8 +133,9 @@ public void queriesWithHavingShouldAnonymizeSensitiveData() { @Test public void queriesWithHighlightShouldAnonymizeSensitiveData() { String query = "SELECT HIGHLIGHT(str0) FROM CALCS WHERE QUERY_STRING(['str0'], 'FURNITURE')"; - String expectedQuery = "( SELECT HIGHLIGHT ( identifier ) FROM table WHERE " - + "QUERY_STRING ( [ 'string_literal' ], 'string_literal' ) )"; + String expectedQuery = + "( SELECT HIGHLIGHT ( identifier ) FROM table WHERE " + + "QUERY_STRING ( [ 'string_literal' ], 'string_literal' ) )"; parse(query); assertEquals(expectedQuery, anonymizerListener.getAnonymizedQueryString()); } @@ -139,8 +143,8 @@ public void queriesWithHighlightShouldAnonymizeSensitiveData() { @Test public void queriesWithMatchShouldAnonymizeSensitiveData() { String query = "SELECT str0 FROM CALCS WHERE MATCH(str0, 'FURNITURE')"; - String expectedQuery = "( SELECT identifier FROM table " - + "WHERE MATCH ( identifier, 'string_literal' ) )"; + String expectedQuery = + "( SELECT identifier FROM table " + "WHERE MATCH ( identifier, 'string_literal' ) )"; parse(query); assertEquals(expectedQuery, anonymizerListener.getAnonymizedQueryString()); } @@ -155,10 +159,12 @@ public void queriesWithPositionShouldAnonymizeSensitiveData() { @Test public void queriesWithMatch_Bool_Prefix_ShouldAnonymizeSensitiveData() { - String query = "SELECT firstname, address FROM accounts WHERE " - + "match_bool_prefix(address, 'Bristol Street', minimum_should_match=2)"; - String expectedQuery = "( SELECT identifier, identifier FROM table WHERE MATCH_BOOL_PREFIX " - + "( identifier, 'string_literal', MINIMUM_SHOULD_MATCH = number ) )"; + String query = + "SELECT firstname, address FROM accounts WHERE " + + "match_bool_prefix(address, 'Bristol Street', minimum_should_match=2)"; + String expectedQuery = + "( SELECT identifier, identifier FROM table WHERE MATCH_BOOL_PREFIX " + + "( identifier, 'string_literal', MINIMUM_SHOULD_MATCH = number ) )"; parse(query); assertEquals(expectedQuery, anonymizerListener.getAnonymizedQueryString()); } @@ -195,10 +201,7 @@ public void queriesWithNotEqualAlternateShouldAnonymizeSensitiveData() { assertEquals(expectedQuery, anonymizerListener.getAnonymizedQueryString()); } - - /** - * Test added for coverage, but the errorNode will not be hit normally. - */ + /** Test added for coverage, but the errorNode will not be hit normally. */ @Test public void enterErrorNote() { ErrorNode node = mock(ErrorNode.class); diff --git a/sql/src/test/java/org/opensearch/sql/sql/parser/AstAggregationBuilderTest.java b/sql/src/test/java/org/opensearch/sql/sql/parser/AstAggregationBuilderTest.java index fff789de44..95188e20b6 100644 --- a/sql/src/test/java/org/opensearch/sql/sql/parser/AstAggregationBuilderTest.java +++ b/sql/src/test/java/org/opensearch/sql/sql/parser/AstAggregationBuilderTest.java @@ -3,7 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ - package org.opensearch.sql.sql.parser; import static java.util.Collections.emptyList; @@ -59,10 +58,9 @@ void can_build_group_by_clause_with_scalar_expression() { buildAggregation("SELECT ABS(age + 1) FROM test GROUP BY ABS(age + 1)"), allOf( hasGroupByItems( - alias("ABS(+(age, 1))", function("ABS", - function("+", - qualifiedName("age"), - intLiteral(1))))), + alias( + "ABS(+(age, 1))", + function("ABS", function("+", qualifiedName("age"), intLiteral(1))))), hasAggregators())); } @@ -79,9 +77,7 @@ void can_build_group_by_clause_with_complicated_aggregators() { void can_build_group_by_clause_without_aggregators() { assertThat( buildAggregation("SELECT state FROM test GROUP BY state"), - allOf( - hasGroupByItems(alias("state", qualifiedName("state"))), - hasAggregators())); + allOf(hasGroupByItems(alias("state", qualifiedName("state"))), hasAggregators())); } @Test @@ -101,50 +97,43 @@ void can_build_implicit_group_by_for_aggregator_in_having_clause() { buildAggregation("SELECT true FROM test HAVING AVG(age) > 30"), allOf( hasGroupByItems(), - hasAggregators( - alias("AVG(age)", aggregate("AVG", qualifiedName("age")))))); + hasAggregators(alias("AVG(age)", aggregate("AVG", qualifiedName("age")))))); assertThat( - buildAggregation("SELECT PI() FROM test HAVING AVG(age) > 30"), - allOf( - hasGroupByItems(), - hasAggregators( - alias("AVG(age)", aggregate("AVG", qualifiedName("age")))))); + buildAggregation("SELECT PI() FROM test HAVING AVG(age) > 30"), + allOf( + hasGroupByItems(), + hasAggregators(alias("AVG(age)", aggregate("AVG", qualifiedName("age")))))); assertThat( - buildAggregation("SELECT ABS(1.5) FROM test HAVING AVG(age) > 30"), - allOf( - hasGroupByItems(), - hasAggregators( - alias("AVG(age)", aggregate("AVG", qualifiedName("age")))))); + buildAggregation("SELECT ABS(1.5) FROM test HAVING AVG(age) > 30"), + allOf( + hasGroupByItems(), + hasAggregators(alias("AVG(age)", aggregate("AVG", qualifiedName("age")))))); assertThat( - buildAggregation("SELECT ABS(ABS(1.5)) FROM test HAVING AVG(age) > 30"), - allOf( - hasGroupByItems(), - hasAggregators( - alias("AVG(age)", aggregate("AVG", qualifiedName("age")))))); + buildAggregation("SELECT ABS(ABS(1.5)) FROM test HAVING AVG(age) > 30"), + allOf( + hasGroupByItems(), + hasAggregators(alias("AVG(age)", aggregate("AVG", qualifiedName("age")))))); assertThat( buildAggregation("SELECT INTERVAL 1 DAY FROM test HAVING AVG(age) > 30"), allOf( hasGroupByItems(), - hasAggregators( - alias("AVG(age)", aggregate("AVG", qualifiedName("age")))))); + hasAggregators(alias("AVG(age)", aggregate("AVG", qualifiedName("age")))))); assertThat( buildAggregation("SELECT CAST(1 AS LONG) FROM test HAVING AVG(age) > 30"), allOf( hasGroupByItems(), - hasAggregators( - alias("AVG(age)", aggregate("AVG", qualifiedName("age")))))); + hasAggregators(alias("AVG(age)", aggregate("AVG", qualifiedName("age")))))); assertThat( buildAggregation("SELECT CASE WHEN true THEN 1 ELSE 2 END FROM test HAVING AVG(age) > 30"), allOf( hasGroupByItems(), - hasAggregators( - alias("AVG(age)", aggregate("AVG", qualifiedName("age")))))); + hasAggregators(alias("AVG(age)", aggregate("AVG", qualifiedName("age")))))); } @Test @@ -154,8 +143,7 @@ void can_build_distinct_aggregator() { allOf( hasGroupByItems(alias("age", qualifiedName("age"))), hasAggregators( - alias("COUNT(DISTINCT name)", distinctAggregate("COUNT", qualifiedName( - "name")))))); + alias("COUNT(DISTINCT name)", distinctAggregate("COUNT", qualifiedName("name")))))); } @Test @@ -167,8 +155,8 @@ void should_build_nothing_if_no_group_by_and_no_aggregators_in_select() { void should_replace_group_by_alias_by_expression_in_select_clause() { assertThat( buildAggregation("SELECT state AS s, name FROM test GROUP BY s, name"), - hasGroupByItems(alias("state", qualifiedName("state")), - alias("name", qualifiedName("name")))); + hasGroupByItems( + alias("state", qualifiedName("state")), alias("name", qualifiedName("name")))); assertThat( buildAggregation("SELECT ABS(age) AS a FROM test GROUP BY a"), @@ -190,25 +178,30 @@ void should_replace_group_by_ordinal_by_expression_in_select_clause() { @Test void should_report_error_for_non_integer_ordinal_in_group_by() { - SemanticCheckException error = assertThrows(SemanticCheckException.class, () -> - buildAggregation("SELECT state AS s FROM test GROUP BY 1.5")); - assertEquals( - "Non-integer constant [1.5] found in ordinal", - error.getMessage()); + SemanticCheckException error = + assertThrows( + SemanticCheckException.class, + () -> buildAggregation("SELECT state AS s FROM test GROUP BY 1.5")); + assertEquals("Non-integer constant [1.5] found in ordinal", error.getMessage()); } - @Disabled("This validation is supposed to be in analyzing phase. This test should be enabled " + @Disabled( + "This validation is supposed to be in analyzing phase. This test should be enabled " + "once https://github.com/opensearch-project/sql/issues/910 has been resolved") @Test void should_report_error_for_mismatch_between_select_and_group_by_items() { - SemanticCheckException error1 = assertThrows(SemanticCheckException.class, () -> - buildAggregation("SELECT name FROM test GROUP BY state")); + SemanticCheckException error1 = + assertThrows( + SemanticCheckException.class, + () -> buildAggregation("SELECT name FROM test GROUP BY state")); assertEquals( "Expression [name] that contains non-aggregated column is not present in group by clause", error1.getMessage()); - SemanticCheckException error2 = assertThrows(SemanticCheckException.class, () -> - buildAggregation("SELECT ABS(name + 1) FROM test GROUP BY name")); + SemanticCheckException error2 = + assertThrows( + SemanticCheckException.class, + () -> buildAggregation("SELECT ABS(name + 1) FROM test GROUP BY name")); assertEquals( "Expression [Function(funcName=ABS, funcArgs=[Function(funcName=+, " + "funcArgs=[name, Literal(value=1, type=INTEGER)])])] that contains " @@ -218,15 +211,19 @@ void should_report_error_for_mismatch_between_select_and_group_by_items() { @Test void should_report_error_for_non_aggregated_item_in_select_if_no_group_by() { - SemanticCheckException error1 = assertThrows(SemanticCheckException.class, () -> - buildAggregation("SELECT age, AVG(balance) FROM tests")); + SemanticCheckException error1 = + assertThrows( + SemanticCheckException.class, + () -> buildAggregation("SELECT age, AVG(balance) FROM tests")); assertEquals( "Explicit GROUP BY clause is required because expression [age] " + "contains non-aggregated column", error1.getMessage()); - SemanticCheckException error2 = assertThrows(SemanticCheckException.class, () -> - buildAggregation("SELECT ABS(age + 1), AVG(balance) FROM tests")); + SemanticCheckException error2 = + assertThrows( + SemanticCheckException.class, + () -> buildAggregation("SELECT ABS(age + 1), AVG(balance) FROM tests")); assertEquals( "Explicit GROUP BY clause is required because expression [ABS(+(age, 1))] " + "contains non-aggregated column", @@ -235,19 +232,25 @@ void should_report_error_for_non_aggregated_item_in_select_if_no_group_by() { @Test void should_report_error_for_group_by_ordinal_out_of_bound_of_select_list() { - SemanticCheckException error1 = assertThrows(SemanticCheckException.class, () -> - buildAggregation("SELECT age, AVG(balance) FROM tests GROUP BY 0")); + SemanticCheckException error1 = + assertThrows( + SemanticCheckException.class, + () -> buildAggregation("SELECT age, AVG(balance) FROM tests GROUP BY 0")); assertEquals("Ordinal [0] is out of bound of select item list", error1.getMessage()); - SemanticCheckException error2 = assertThrows(SemanticCheckException.class, () -> - buildAggregation("SELECT age, AVG(balance) FROM tests GROUP BY 3")); + SemanticCheckException error2 = + assertThrows( + SemanticCheckException.class, + () -> buildAggregation("SELECT age, AVG(balance) FROM tests GROUP BY 3")); assertEquals("Ordinal [3] is out of bound of select item list", error2.getMessage()); } @Test void should_report_error_for_non_aggregated_item_in_select_if_only_having() { - SemanticCheckException error = assertThrows(SemanticCheckException.class, () -> - buildAggregation("SELECT age FROM tests HAVING AVG(balance) > 30")); + SemanticCheckException error = + assertThrows( + SemanticCheckException.class, + () -> buildAggregation("SELECT age FROM tests HAVING AVG(balance) > 30")); assertEquals( "Explicit GROUP BY clause is required because expression [age] " + "contains non-aggregated column", @@ -262,10 +265,10 @@ private Matcher hasAggregators(UnresolvedExpression... exprs) { return featureValueOf("aggregators", Aggregation::getAggExprList, exprs); } - private Matcher featureValueOf(String name, - Function> getter, - UnresolvedExpression... exprs) { + private Matcher featureValueOf( + String name, + Function> getter, + UnresolvedExpression... exprs) { Matcher> subMatcher = (exprs.length == 0) ? equalTo(emptyList()) : equalTo(Arrays.asList(exprs)); return new FeatureMatcher>(subMatcher, name, "") { @@ -295,5 +298,4 @@ private QuerySpecificationContext parse(String query) { parser.addErrorListener(new SyntaxAnalysisErrorListener()); return parser.querySpecification(); } - } diff --git a/sql/src/test/java/org/opensearch/sql/sql/parser/AstBuilderTest.java b/sql/src/test/java/org/opensearch/sql/sql/parser/AstBuilderTest.java index 3e56a89754..f1f42dc219 100644 --- a/sql/src/test/java/org/opensearch/sql/sql/parser/AstBuilderTest.java +++ b/sql/src/test/java/org/opensearch/sql/sql/parser/AstBuilderTest.java @@ -3,7 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ - package org.opensearch.sql.sql.parser; import static java.util.Collections.emptyList; @@ -53,36 +52,20 @@ public void can_build_select_literals() { alias("'hello'", stringLiteral("hello")), alias("\"world\"", stringLiteral("world")), alias("false", booleanLiteral(false)), - alias("-4.567", doubleLiteral(-4.567)) - ), - buildAST("SELECT 123, 'hello', \"world\", false, -4.567") - ); + alias("-4.567", doubleLiteral(-4.567))), + buildAST("SELECT 123, 'hello', \"world\", false, -4.567")); } @Test public void can_build_select_function_call_with_alias() { assertEquals( - project( - relation("test"), - alias( - "ABS(age)", - function("ABS", qualifiedName("age")), - "a" - ) - ), - buildAST("SELECT ABS(age) AS a FROM test") - ); + project(relation("test"), alias("ABS(age)", function("ABS", qualifiedName("age")), "a")), + buildAST("SELECT ABS(age) AS a FROM test")); } @Test public void can_build_select_all_from_index() { - assertEquals( - project( - relation("test"), - AllFields.of() - ), - buildAST("SELECT * FROM test") - ); + assertEquals(project(relation("test"), AllFields.of()), buildAST("SELECT * FROM test")); assertThrows(SyntaxCheckException.class, () -> buildAST("SELECT *")); } @@ -90,14 +73,8 @@ public void can_build_select_all_from_index() { @Test public void can_build_nested_select_all() { assertEquals( - project( - relation("test"), - alias("nested(field.*)", - new NestedAllTupleFields("field") - ) - ), - buildAST("SELECT nested(field.*) FROM test") - ); + project(relation("test"), alias("nested(field.*)", new NestedAllTupleFields("field"))), + buildAST("SELECT nested(field.*) FROM test")); } @Test @@ -107,32 +84,22 @@ public void can_build_select_all_and_fields_from_index() { relation("test"), AllFields.of(), alias("age", qualifiedName("age")), - alias("age", qualifiedName("age"), "a") - ), - buildAST("SELECT *, age, age as a FROM test") - ); + alias("age", qualifiedName("age"), "a")), + buildAST("SELECT *, age, age as a FROM test")); } @Test public void can_build_select_fields_from_index() { assertEquals( - project( - relation("test"), - alias("age", qualifiedName("age")) - ), - buildAST("SELECT age FROM test") - ); + project(relation("test"), alias("age", qualifiedName("age"))), + buildAST("SELECT age FROM test")); } @Test public void can_build_select_fields_with_alias() { assertEquals( - project( - relation("test"), - alias("age", qualifiedName("age"), "a") - ), - buildAST("SELECT age AS a FROM test") - ); + project(relation("test"), alias("age", qualifiedName("age"), "a")), + buildAST("SELECT age AS a FROM test")); } @Test @@ -140,17 +107,8 @@ public void can_build_select_fields_with_alias_quoted() { assertEquals( project( relation("test"), - alias( - "(age + 10)", - function("+", qualifiedName("age"), intLiteral(10)), - "Age_Expr" - ) - ), - buildAST("SELECT" - + " (age + 10) AS `Age_Expr` " - + "FROM test" - ) - ); + alias("(age + 10)", function("+", qualifiedName("age"), intLiteral(10)), "Age_Expr")), + buildAST("SELECT" + " (age + 10) AS `Age_Expr` " + "FROM test")); } @Test @@ -158,42 +116,27 @@ public void can_build_from_index_with_alias() { assertEquals( project( filter( - relation("test", "tt"), - function("=", qualifiedName("tt", "age"), intLiteral(30))), - alias("tt.name", qualifiedName("tt", "name")) - ), - buildAST("SELECT tt.name FROM test AS tt WHERE tt.age = 30") - ); + relation("test", "tt"), function("=", qualifiedName("tt", "age"), intLiteral(30))), + alias("tt.name", qualifiedName("tt", "name"))), + buildAST("SELECT tt.name FROM test AS tt WHERE tt.age = 30")); } @Test public void can_build_from_index_with_alias_quoted() { assertEquals( project( - filter( - relation("test", "t"), - function("=", qualifiedName("t", "age"), intLiteral(30))), - alias("`t`.name", qualifiedName("t", "name")) - ), - buildAST("SELECT `t`.name FROM test `t` WHERE `t`.age = 30") - ); + filter(relation("test", "t"), function("=", qualifiedName("t", "age"), intLiteral(30))), + alias("`t`.name", qualifiedName("t", "name"))), + buildAST("SELECT `t`.name FROM test `t` WHERE `t`.age = 30")); } @Test public void can_build_where_clause() { assertEquals( project( - filter( - relation("test"), - function( - "=", - qualifiedName("name"), - stringLiteral("John")) - ), - alias("name", qualifiedName("name")) - ), - buildAST("SELECT name FROM test WHERE name = 'John'") - ); + filter(relation("test"), function("=", qualifiedName("name"), stringLiteral("John"))), + alias("name", qualifiedName("name"))), + buildAST("SELECT name FROM test WHERE name = 'John'")); } @Test @@ -202,8 +145,7 @@ public void can_build_count_literal() { project( agg( relation("test"), - ImmutableList.of( - alias("COUNT(1)", aggregate("COUNT", intLiteral(1)))), + ImmutableList.of(alias("COUNT(1)", aggregate("COUNT", intLiteral(1)))), emptyList(), emptyList(), emptyList()), @@ -217,8 +159,7 @@ public void can_build_count_star() { project( agg( relation("test"), - ImmutableList.of( - alias("COUNT(*)", aggregate("COUNT", AllFields.of()))), + ImmutableList.of(alias("COUNT(*)", aggregate("COUNT", AllFields.of()))), emptyList(), emptyList(), emptyList()), @@ -328,9 +269,7 @@ public void can_build_having_clause() { emptyList(), ImmutableList.of(alias("name", qualifiedName("name"))), emptyList()), - function(">", - aggregate("MIN", qualifiedName("balance")), - intLiteral(1000))), + function(">", aggregate("MIN", qualifiedName("balance")), intLiteral(1000))), alias("name", qualifiedName("name")), alias("AVG(age)", aggregate("AVG", qualifiedName("age")))), buildAST("SELECT name, AVG(age) FROM test GROUP BY name HAVING MIN(balance) > 1000")); @@ -343,14 +282,11 @@ public void can_build_having_condition_using_alias() { filter( agg( relation("test"), - ImmutableList.of( - alias("AVG(age)", aggregate("AVG", qualifiedName("age")))), + ImmutableList.of(alias("AVG(age)", aggregate("AVG", qualifiedName("age")))), emptyList(), ImmutableList.of(alias("name", qualifiedName("name"))), emptyList()), - function(">", - aggregate("AVG", qualifiedName("age")), - intLiteral(1000))), + function(">", aggregate("AVG", qualifiedName("age")), intLiteral(1000))), alias("name", qualifiedName("name")), alias("AVG(age)", aggregate("AVG", qualifiedName("age")), "a")), buildAST("SELECT name, AVG(age) AS a FROM test GROUP BY name HAVING a > 1000")); @@ -360,9 +296,7 @@ public void can_build_having_condition_using_alias() { public void can_build_order_by_field_name() { assertEquals( project( - sort( - relation("test"), - field("name", argument("asc", booleanLiteral(true)))), + sort(relation("test"), field("name", argument("asc", booleanLiteral(true)))), alias("name", qualifiedName("name"))), buildAST("SELECT name FROM test ORDER BY name")); } @@ -374,8 +308,7 @@ public void can_build_order_by_function() { sort( relation("test"), field( - function("ABS", qualifiedName("name")), - argument("asc", booleanLiteral(true)))), + function("ABS", qualifiedName("name")), argument("asc", booleanLiteral(true)))), alias("name", qualifiedName("name"))), buildAST("SELECT name FROM test ORDER BY ABS(name)")); } @@ -384,9 +317,7 @@ public void can_build_order_by_function() { public void can_build_order_by_alias() { assertEquals( project( - sort( - relation("test"), - field("name", argument("asc", booleanLiteral(true)))), + sort(relation("test"), field("name", argument("asc", booleanLiteral(true)))), alias("name", qualifiedName("name"), "n")), buildAST("SELECT name AS n FROM test ORDER BY n ASC")); } @@ -395,9 +326,7 @@ public void can_build_order_by_alias() { public void can_build_order_by_ordinal() { assertEquals( project( - sort( - relation("test"), - field("name", argument("asc", booleanLiteral(false)))), + sort(relation("test"), field("name", argument("asc", booleanLiteral(false)))), alias("name", qualifiedName("name"))), buildAST("SELECT name FROM test ORDER BY 1 DESC")); } @@ -424,8 +353,7 @@ public void can_build_select_distinct_clause() { emptyList(), emptyList(), ImmutableList.of( - alias("name", qualifiedName("name")), - alias("age", qualifiedName("age"))), + alias("name", qualifiedName("name")), alias("age", qualifiedName("age"))), emptyList()), alias("name", qualifiedName("name")), alias("age", qualifiedName("age"))), @@ -441,26 +369,21 @@ public void can_build_select_distinct_clause_with_function() { emptyList(), emptyList(), ImmutableList.of( - alias("SUBSTRING(name, 1, 2)", + alias( + "SUBSTRING(name, 1, 2)", function( - "SUBSTRING", - qualifiedName("name"), - intLiteral(1), intLiteral(2)))), + "SUBSTRING", qualifiedName("name"), intLiteral(1), intLiteral(2)))), emptyList()), - alias("SUBSTRING(name, 1, 2)", - function( - "SUBSTRING", - qualifiedName("name"), - intLiteral(1), intLiteral(2)))), + alias( + "SUBSTRING(name, 1, 2)", + function("SUBSTRING", qualifiedName("name"), intLiteral(1), intLiteral(2)))), buildAST("SELECT DISTINCT SUBSTRING(name, 1, 2) FROM test")); } @Test public void can_build_select_all_clause() { assertEquals( - buildAST("SELECT name, age FROM test"), - buildAST("SELECT ALL name, age FROM test") - ); + buildAST("SELECT name, age FROM test"), buildAST("SELECT ALL name, age FROM test")); } @Test @@ -469,22 +392,28 @@ public void can_build_order_by_null_option() { project( sort( relation("test"), - field("name", + field( + "name", argument("asc", booleanLiteral(true)), argument("nullFirst", booleanLiteral(false)))), - alias("name", qualifiedName("name"))), + alias("name", qualifiedName("name"))), buildAST("SELECT name FROM test ORDER BY name NULLS LAST")); } /** + * + * + *
    * Ensure Nested function falls back to legacy engine when used in an HAVING clause.
    * TODO Remove this test when support is added.
+   * 
*/ @Test public void nested_in_having_clause_throws_exception() { - SyntaxCheckException exception = assertThrows(SyntaxCheckException.class, - () -> buildAST("SELECT count(*) FROM test HAVING nested(message.info)") - ); + SyntaxCheckException exception = + assertThrows( + SyntaxCheckException.class, + () -> buildAST("SELECT count(*) FROM test HAVING nested(message.info)")); assertEquals( "Falling back to legacy engine. Nested function is not supported in the HAVING clause.", @@ -495,23 +424,15 @@ public void nested_in_having_clause_throws_exception() { public void can_build_order_by_sort_order_keyword_insensitive() { assertEquals( project( - sort( - relation("test"), - field("age", - argument("asc", booleanLiteral(true)))), + sort(relation("test"), field("age", argument("asc", booleanLiteral(true)))), alias("age", qualifiedName("age"))), - buildAST("SELECT age FROM test ORDER BY age ASC") - ); + buildAST("SELECT age FROM test ORDER BY age ASC")); assertEquals( project( - sort( - relation("test"), - field("age", - argument("asc", booleanLiteral(true)))), + sort(relation("test"), field("age", argument("asc", booleanLiteral(true)))), alias("age", qualifiedName("age"))), - buildAST("SELECT age FROM test ORDER BY age asc") - ); + buildAST("SELECT age FROM test ORDER BY age asc")); } @Test @@ -523,20 +444,15 @@ public void can_build_from_subquery() { project( relation("test"), alias("firstname", qualifiedName("firstname"), "firstName"), - alias("lastname", qualifiedName("lastname"), "lastName") - ), - "a" - ), - function(">", qualifiedName("age"), intLiteral(20)) - ), + alias("lastname", qualifiedName("lastname"), "lastName")), + "a"), + function(">", qualifiedName("age"), intLiteral(20))), alias("a.firstName", qualifiedName("a", "firstName")), alias("lastName", qualifiedName("lastName"))), buildAST( "SELECT a.firstName, lastName FROM (" + "SELECT firstname AS firstName, lastname AS lastName FROM test" - + ") AS a where age > 20" - ) - ); + + ") AS a where age > 20")); } @Test @@ -545,19 +461,15 @@ public void can_build_from_subquery_with_backquoted_alias() { project( relationSubquery( project( - relation("test"), - alias("firstname", qualifiedName("firstname"), "firstName")), + relation("test"), alias("firstname", qualifiedName("firstname"), "firstName")), "a"), - alias("a.firstName", qualifiedName("a", "firstName")) - ), + alias("a.firstName", qualifiedName("a", "firstName"))), buildAST( "SELECT a.firstName " + "FROM ( " + " SELECT `firstname` AS `firstName` " + " FROM `test` " - + ") AS `a`" - ) - ); + + ") AS `a`")); } @Test @@ -566,12 +478,9 @@ public void can_build_show_all_tables() { project( filter( relation(TABLE_INFO), - function("like", qualifiedName("TABLE_NAME"), stringLiteral("%")) - ), - AllFields.of() - ), - buildAST("SHOW TABLES LIKE '%'") - ); + function("like", qualifiedName("TABLE_NAME"), stringLiteral("%"))), + AllFields.of()), + buildAST("SHOW TABLES LIKE '%'")); } @Test @@ -580,12 +489,9 @@ public void can_build_show_selected_tables() { project( filter( relation(TABLE_INFO), - function("like", qualifiedName("TABLE_NAME"), stringLiteral("a_c%")) - ), - AllFields.of() - ), - buildAST("SHOW TABLES LIKE 'a_c%'") - ); + function("like", qualifiedName("TABLE_NAME"), stringLiteral("a_c%"))), + AllFields.of()), + buildAST("SHOW TABLES LIKE 'a_c%'")); } @Test @@ -594,23 +500,16 @@ public void show_compatible_with_old_engine_syntax() { project( filter( relation(TABLE_INFO), - function("like", qualifiedName("TABLE_NAME"), stringLiteral("%")) - ), - AllFields.of() - ), - buildAST("SHOW TABLES LIKE '%'") - ); + function("like", qualifiedName("TABLE_NAME"), stringLiteral("%"))), + AllFields.of()), + buildAST("SHOW TABLES LIKE '%'")); } @Test public void can_build_describe_selected_tables() { assertEquals( - project( - relation(mappingTable("a_c%")), - AllFields.of() - ), - buildAST("DESCRIBE TABLES LIKE 'a_c%'") - ); + project(relation(mappingTable("a_c%")), AllFields.of()), + buildAST("DESCRIBE TABLES LIKE 'a_c%'")); } @Test @@ -619,23 +518,16 @@ public void can_build_describe_selected_tables_field_filter() { project( filter( relation(mappingTable("a_c%")), - function("like", qualifiedName("COLUMN_NAME"), stringLiteral("name%")) - ), - AllFields.of() - ), - buildAST("DESCRIBE TABLES LIKE 'a_c%' COLUMNS LIKE 'name%'") - ); + function("like", qualifiedName("COLUMN_NAME"), stringLiteral("name%"))), + AllFields.of()), + buildAST("DESCRIBE TABLES LIKE 'a_c%' COLUMNS LIKE 'name%'")); } @Test public void can_build_alias_by_keywords() { assertEquals( - project( - relation("test"), - alias("avg_age", qualifiedName("avg_age"), "avg") - ), - buildAST("SELECT avg_age AS avg FROM test") - ); + project(relation("test"), alias("avg_age", qualifiedName("avg_age"), "avg")), + buildAST("SELECT avg_age AS avg FROM test")); } @Test @@ -643,42 +535,20 @@ public void can_build_limit_clause() { assertEquals( project( limit( - sort( - relation("test"), - field("age", argument("asc", booleanLiteral(true))) - ), - 10, - 0 - ), + sort(relation("test"), field("age", argument("asc", booleanLiteral(true)))), 10, 0), alias("name", qualifiedName("name")), - alias("age", qualifiedName("age")) - ), - buildAST("SELECT name, age FROM test ORDER BY age LIMIT 10") - ); + alias("age", qualifiedName("age"))), + buildAST("SELECT name, age FROM test ORDER BY age LIMIT 10")); } @Test public void can_build_limit_clause_with_offset() { assertEquals( - project( - limit( - relation("test"), - 10, - 5 - ), - alias("name", qualifiedName("name")) - ), + project(limit(relation("test"), 10, 5), alias("name", qualifiedName("name"))), buildAST("SELECT name FROM test LIMIT 10 OFFSET 5")); assertEquals( - project( - limit( - relation("test"), - 10, - 5 - ), - alias("name", qualifiedName("name")) - ), + project(limit(relation("test"), 10, 5), alias("name", qualifiedName("name"))), buildAST("SELECT name FROM test LIMIT 5, 10")); } @@ -686,11 +556,10 @@ public void can_build_limit_clause_with_offset() { public void can_build_qualified_name_highlight() { Map args = new HashMap<>(); assertEquals( - project(relation("test"), - alias("highlight(fieldA)", - highlight(AstDSL.qualifiedName("fieldA"), args))), - buildAST("SELECT highlight(fieldA) FROM test") - ); + project( + relation("test"), + alias("highlight(fieldA)", highlight(AstDSL.qualifiedName("fieldA"), args))), + buildAST("SELECT highlight(fieldA) FROM test")); } @Test @@ -699,22 +568,22 @@ public void can_build_qualified_highlight_with_arguments() { args.put("pre_tags", new Literal("", DataType.STRING)); args.put("post_tags", new Literal("", DataType.STRING)); assertEquals( - project(relation("test"), - alias("highlight(fieldA, pre_tags='', post_tags='')", + project( + relation("test"), + alias( + "highlight(fieldA, pre_tags='', post_tags='')", highlight(AstDSL.qualifiedName("fieldA"), args))), - buildAST("SELECT highlight(fieldA, pre_tags='', post_tags='') " - + "FROM test") - ); + buildAST( + "SELECT highlight(fieldA, pre_tags='', post_tags='') " + "FROM test")); } @Test public void can_build_string_literal_highlight() { Map args = new HashMap<>(); assertEquals( - project(relation("test"), - alias("highlight(\"fieldA\")", - highlight(AstDSL.stringLiteral("fieldA"), args))), - buildAST("SELECT highlight(\"fieldA\") FROM test") - ); + project( + relation("test"), + alias("highlight(\"fieldA\")", highlight(AstDSL.stringLiteral("fieldA"), args))), + buildAST("SELECT highlight(\"fieldA\") FROM test")); } } diff --git a/sql/src/test/java/org/opensearch/sql/sql/parser/AstBuilderTestBase.java b/sql/src/test/java/org/opensearch/sql/sql/parser/AstBuilderTestBase.java index 2161eb5b1a..602f17ce85 100644 --- a/sql/src/test/java/org/opensearch/sql/sql/parser/AstBuilderTestBase.java +++ b/sql/src/test/java/org/opensearch/sql/sql/parser/AstBuilderTestBase.java @@ -10,9 +10,7 @@ import org.opensearch.sql.sql.antlr.SQLSyntaxParser; public class AstBuilderTestBase { - /** - * SQL syntax parser that helps prepare parse tree as AstBuilder input. - */ + /** SQL syntax parser that helps prepare parse tree as AstBuilder input. */ private final SQLSyntaxParser parser = new SQLSyntaxParser(); protected UnresolvedPlan buildAST(String query) { diff --git a/sql/src/test/java/org/opensearch/sql/sql/parser/AstExpressionBuilderTest.java b/sql/src/test/java/org/opensearch/sql/sql/parser/AstExpressionBuilderTest.java index 20655bc020..f2e7fdb2d8 100644 --- a/sql/src/test/java/org/opensearch/sql/sql/parser/AstExpressionBuilderTest.java +++ b/sql/src/test/java/org/opensearch/sql/sql/parser/AstExpressionBuilderTest.java @@ -3,7 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ - package org.opensearch.sql.sql.parser; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -57,185 +56,122 @@ class AstExpressionBuilderTest { @Test public void canBuildStringLiteral() { - assertEquals( - stringLiteral("hello"), - buildExprAst("'hello'") - ); - assertEquals( - stringLiteral("hello"), - buildExprAst("\"hello\"") - ); + assertEquals(stringLiteral("hello"), buildExprAst("'hello'")); + assertEquals(stringLiteral("hello"), buildExprAst("\"hello\"")); } @Test public void canBuildIntegerLiteral() { - assertEquals( - intLiteral(123), - buildExprAst("123") - ); - assertEquals( - intLiteral(Integer.MAX_VALUE), - buildExprAst(String.valueOf(Integer.MAX_VALUE)) - ); - assertEquals( - intLiteral(Integer.MIN_VALUE), - buildExprAst(String.valueOf(Integer.MIN_VALUE)) - ); + assertEquals(intLiteral(123), buildExprAst("123")); + assertEquals(intLiteral(Integer.MAX_VALUE), buildExprAst(String.valueOf(Integer.MAX_VALUE))); + assertEquals(intLiteral(Integer.MIN_VALUE), buildExprAst(String.valueOf(Integer.MIN_VALUE))); } @Test public void canBuildLongLiteral() { + assertEquals(longLiteral(1234567890123L), buildExprAst("1234567890123")); assertEquals( - longLiteral(1234567890123L), - buildExprAst("1234567890123") - ); + longLiteral(Integer.MAX_VALUE + 1L), buildExprAst(String.valueOf(Integer.MAX_VALUE + 1L))); assertEquals( - longLiteral(Integer.MAX_VALUE + 1L), - buildExprAst(String.valueOf(Integer.MAX_VALUE + 1L)) - ); - assertEquals( - longLiteral(Integer.MIN_VALUE - 1L), - buildExprAst(String.valueOf(Integer.MIN_VALUE - 1L)) - ); + longLiteral(Integer.MIN_VALUE - 1L), buildExprAst(String.valueOf(Integer.MIN_VALUE - 1L))); } @Test public void canBuildNegativeRealLiteral() { - assertEquals( - doubleLiteral(-4.567), - buildExprAst("-4.567") - ); + assertEquals(doubleLiteral(-4.567), buildExprAst("-4.567")); } @Test public void canBuildBooleanLiteral() { - assertEquals( - booleanLiteral(true), - buildExprAst("true") - ); + assertEquals(booleanLiteral(true), buildExprAst("true")); } @Test public void canBuildDateLiteral() { - assertEquals( - dateLiteral("2020-07-07"), - buildExprAst("DATE '2020-07-07'") - ); + assertEquals(dateLiteral("2020-07-07"), buildExprAst("DATE '2020-07-07'")); } @Test public void canBuildTimeLiteral() { - assertEquals( - timeLiteral("11:30:45"), - buildExprAst("TIME '11:30:45'") - ); + assertEquals(timeLiteral("11:30:45"), buildExprAst("TIME '11:30:45'")); } @Test public void canBuildTimestampLiteral() { assertEquals( - timestampLiteral("2020-07-07 11:30:45"), - buildExprAst("TIMESTAMP '2020-07-07 11:30:45'") - ); + timestampLiteral("2020-07-07 11:30:45"), buildExprAst("TIMESTAMP '2020-07-07 11:30:45'")); } @Test public void canBuildIntervalLiteral() { - assertEquals( - intervalLiteral(1, DataType.INTEGER, "day"), - buildExprAst("interval 1 day") - ); + assertEquals(intervalLiteral(1, DataType.INTEGER, "day"), buildExprAst("interval 1 day")); } @Test public void canBuildArithmeticExpression() { - assertEquals( - function("+", intLiteral(1), intLiteral(2)), - buildExprAst("1 + 2") - ); + assertEquals(function("+", intLiteral(1), intLiteral(2)), buildExprAst("1 + 2")); } @Test public void canBuildArithmeticExpressionPrecedence() { assertEquals( - function("+", - intLiteral(1), - function("*", - intLiteral(2), intLiteral(3))), - buildExprAst("1 + 2 * 3") - ); + function("+", intLiteral(1), function("*", intLiteral(2), intLiteral(3))), + buildExprAst("1 + 2 * 3")); } @Test public void canBuildFunctionWithoutArguments() { - assertEquals( - function("PI"), - buildExprAst("PI()") - ); + assertEquals(function("PI"), buildExprAst("PI()")); } @Test public void canBuildExpressionWithParentheses() { assertEquals( - function("*", + function( + "*", function("+", doubleLiteral(-1.0), doubleLiteral(2.3)), - function("-", intLiteral(3), intLiteral(1)) - ), - buildExprAst("(-1.0 + 2.3) * (3 - 1)") - ); + function("-", intLiteral(3), intLiteral(1))), + buildExprAst("(-1.0 + 2.3) * (3 - 1)")); } @Test public void canBuildFunctionCall() { - assertEquals( - function("abs", intLiteral(-1)), - buildExprAst("abs(-1)") - ); + assertEquals(function("abs", intLiteral(-1)), buildExprAst("abs(-1)")); } @Test public void canBuildExtractFunctionCall() { assertEquals( function("extract", stringLiteral("DAY"), dateLiteral("2023-02-09")).toString(), - buildExprAst("extract(DAY FROM \"2023-02-09\")").toString() - ); + buildExprAst("extract(DAY FROM \"2023-02-09\")").toString()); } @Test public void canBuildGetFormatFunctionCall() { assertEquals( function("get_format", stringLiteral("DATE"), stringLiteral("USA")), - buildExprAst("get_format(DATE,\"USA\")") - ); + buildExprAst("get_format(DATE,\"USA\")")); } @Test public void canBuildNestedFunctionCall() { assertEquals( - function("abs", - function("*", - function("abs", intLiteral(-5)), - intLiteral(-1) - ) - ), - buildExprAst("abs(abs(-5) * -1)") - ); + function("abs", function("*", function("abs", intLiteral(-5)), intLiteral(-1))), + buildExprAst("abs(abs(-5) * -1)")); } @Test public void canBuildDateAndTimeFunctionCall() { assertEquals( function("dayofmonth", dateLiteral("2020-07-07")), - buildExprAst("dayofmonth(DATE '2020-07-07')") - ); + buildExprAst("dayofmonth(DATE '2020-07-07')")); } @Test public void canBuildTimestampAddFunctionCall() { assertEquals( function("timestampadd", stringLiteral("WEEK"), intLiteral(1), dateLiteral("2023-03-14")), - buildExprAst("timestampadd(WEEK, 1, DATE '2023-03-14')") - ); + buildExprAst("timestampadd(WEEK, 1, DATE '2023-03-14')")); } @Test @@ -246,105 +182,69 @@ public void canBuildTimstampDiffFunctionCall() { stringLiteral("WEEK"), timestampLiteral("2023-03-15 00:00:01"), dateLiteral("2023-03-14")), - buildExprAst("timestampdiff(WEEK, TIMESTAMP '2023-03-15 00:00:01', DATE '2023-03-14')") - ); + buildExprAst("timestampdiff(WEEK, TIMESTAMP '2023-03-15 00:00:01', DATE '2023-03-14')")); } @Test public void canBuildComparisonExpression() { - assertEquals( - function("!=", intLiteral(1), intLiteral(2)), - buildExprAst("1 != 2") - ); + assertEquals(function("!=", intLiteral(1), intLiteral(2)), buildExprAst("1 != 2")); - assertEquals( - function("!=", intLiteral(1), intLiteral(2)), - buildExprAst("1 <> 2") - ); + assertEquals(function("!=", intLiteral(1), intLiteral(2)), buildExprAst("1 <> 2")); } @Test public void canBuildNullTestExpression() { - assertEquals( - function("is null", intLiteral(1)), - buildExprAst("1 is NULL") - ); + assertEquals(function("is null", intLiteral(1)), buildExprAst("1 is NULL")); - assertEquals( - function("is not null", intLiteral(1)), - buildExprAst("1 IS NOT null") - ); + assertEquals(function("is not null", intLiteral(1)), buildExprAst("1 IS NOT null")); } @Test public void canBuildNullTestExpressionWithNULLLiteral() { - assertEquals( - function("is null", nullLiteral()), - buildExprAst("NULL is NULL") - ); + assertEquals(function("is null", nullLiteral()), buildExprAst("NULL is NULL")); - assertEquals( - function("is not null", nullLiteral()), - buildExprAst("NULL IS NOT null") - ); + assertEquals(function("is not null", nullLiteral()), buildExprAst("NULL IS NOT null")); } @Test public void canBuildLikeExpression() { assertEquals( function("like", stringLiteral("str"), stringLiteral("st%")), - buildExprAst("'str' like 'st%'") - ); + buildExprAst("'str' like 'st%'")); assertEquals( function("not like", stringLiteral("str"), stringLiteral("st%")), - buildExprAst("'str' not like 'st%'") - ); + buildExprAst("'str' not like 'st%'")); } @Test public void canBuildRegexpExpression() { assertEquals( function("regexp", stringLiteral("str"), stringLiteral(".*")), - buildExprAst("'str' regexp '.*'") - ); + buildExprAst("'str' regexp '.*'")); } @Test public void canBuildBetweenExpression() { assertEquals( - between( - qualifiedName("age"), intLiteral(10), intLiteral(30)), - buildExprAst("age BETWEEN 10 AND 30") - ); + between(qualifiedName("age"), intLiteral(10), intLiteral(30)), + buildExprAst("age BETWEEN 10 AND 30")); } @Test public void canBuildNotBetweenExpression() { assertEquals( - not( - between( - qualifiedName("age"), intLiteral(10), intLiteral(30))), - buildExprAst("age NOT BETWEEN 10 AND 30") - ); + not(between(qualifiedName("age"), intLiteral(10), intLiteral(30))), + buildExprAst("age NOT BETWEEN 10 AND 30")); } @Test public void canBuildLogicalExpression() { - assertEquals( - and(booleanLiteral(true), booleanLiteral(false)), - buildExprAst("true AND false") - ); + assertEquals(and(booleanLiteral(true), booleanLiteral(false)), buildExprAst("true AND false")); - assertEquals( - or(booleanLiteral(true), booleanLiteral(false)), - buildExprAst("true OR false") - ); + assertEquals(or(booleanLiteral(true), booleanLiteral(false)), buildExprAst("true OR false")); - assertEquals( - not(booleanLiteral(false)), - buildExprAst("NOT false") - ); + assertEquals(not(booleanLiteral(false)), buildExprAst("NOT false")); } @Test @@ -373,8 +273,8 @@ public void canBuildWindowFunctionWithNullOrderSpecified() { window( function("DENSE_RANK"), ImmutableList.of(), - ImmutableList.of(ImmutablePair.of( - new SortOption(ASC, NULL_LAST), qualifiedName("age")))), + ImmutableList.of( + ImmutablePair.of(new SortOption(ASC, NULL_LAST), qualifiedName("age")))), buildExprAst("DENSE_RANK() OVER (ORDER BY age ASC NULLS LAST)")); } @@ -382,35 +282,27 @@ public void canBuildWindowFunctionWithNullOrderSpecified() { public void canBuildStringLiteralHighlightFunction() { HashMap args = new HashMap<>(); assertEquals( - highlight(AstDSL.stringLiteral("fieldA"), args), - buildExprAst("highlight(\"fieldA\")") - ); + highlight(AstDSL.stringLiteral("fieldA"), args), buildExprAst("highlight(\"fieldA\")")); } @Test public void canBuildQualifiedNameHighlightFunction() { HashMap args = new HashMap<>(); assertEquals( - highlight(AstDSL.qualifiedName("fieldA"), args), - buildExprAst("highlight(fieldA)") - ); + highlight(AstDSL.qualifiedName("fieldA"), args), buildExprAst("highlight(fieldA)")); } @Test public void canBuildStringLiteralPositionFunction() { assertEquals( - function("position", stringLiteral("substr"), stringLiteral("str")), - buildExprAst("position(\"substr\" IN \"str\")") - ); + function("position", stringLiteral("substr"), stringLiteral("str")), + buildExprAst("position(\"substr\" IN \"str\")")); } @Test public void canBuildWindowFunctionWithoutOrderBy() { assertEquals( - window( - function("RANK"), - ImmutableList.of(qualifiedName("state")), - ImmutableList.of()), + window(function("RANK"), ImmutableList.of(qualifiedName("state")), ImmutableList.of()), buildExprAst("RANK() OVER (PARTITION BY state)")); } @@ -420,8 +312,7 @@ public void canBuildAggregateWindowFunction() { window( aggregate("AVG", qualifiedName("age")), ImmutableList.of(qualifiedName("state")), - ImmutableList.of(ImmutablePair.of( - new SortOption(null, null), qualifiedName("age")))), + ImmutableList.of(ImmutablePair.of(new SortOption(null, null), qualifiedName("age")))), buildExprAst("AVG(age) OVER (PARTITION BY state ORDER BY age)")); } @@ -430,11 +321,8 @@ public void canBuildCaseConditionStatement() { assertEquals( caseWhen( null, // no else statement - when( - function(">", qualifiedName("age"), intLiteral(30)), - stringLiteral("age1"))), - buildExprAst("CASE WHEN age > 30 THEN 'age1' END") - ); + when(function(">", qualifiedName("age"), intLiteral(30)), stringLiteral("age1"))), + buildExprAst("CASE WHEN age > 30 THEN 'age1' END")); } @Test @@ -444,168 +332,147 @@ public void canBuildCaseValueStatement() { qualifiedName("age"), stringLiteral("age2"), when(intLiteral(30), stringLiteral("age1"))), - buildExprAst("CASE age WHEN 30 THEN 'age1' ELSE 'age2' END") - ); + buildExprAst("CASE age WHEN 30 THEN 'age1' ELSE 'age2' END")); } @Test public void canBuildKeywordsAsIdentifiers() { - assertEquals( - qualifiedName("timestamp"), - buildExprAst("timestamp") - ); + assertEquals(qualifiedName("timestamp"), buildExprAst("timestamp")); } @Test public void canBuildKeywordsAsIdentInQualifiedName() { - assertEquals( - qualifiedName("test", "timestamp"), - buildExprAst("test.timestamp") - ); + assertEquals(qualifiedName("test", "timestamp"), buildExprAst("test.timestamp")); } @Test public void canBuildMetaDataFieldAsQualifiedName() { - Stream.of("_id", "_index", "_sort", "_score", "_maxscore").forEach( - field -> assertEquals( - qualifiedName(field), - buildExprAst(field) - ) - ); + Stream.of("_id", "_index", "_sort", "_score", "_maxscore") + .forEach(field -> assertEquals(qualifiedName(field), buildExprAst(field))); } @Test public void canBuildNonMetaDataFieldAsQualifiedName() { - Stream.of("id", "__id", "_routing", "___field").forEach( - field -> assertEquals( - qualifiedName(field), - buildExprAst(field) - ) - ); + Stream.of("id", "__id", "_routing", "___field") + .forEach(field -> assertEquals(qualifiedName(field), buildExprAst(field))); } @Test public void canCastFieldAsString() { assertEquals( AstDSL.cast(qualifiedName("state"), stringLiteral("string")), - buildExprAst("cast(state as string)") - ); + buildExprAst("cast(state as string)")); } @Test public void canCastValueAsString() { assertEquals( - AstDSL.cast(intLiteral(1), stringLiteral("string")), - buildExprAst("cast(1 as string)") - ); + AstDSL.cast(intLiteral(1), stringLiteral("string")), buildExprAst("cast(1 as string)")); } @Test public void filteredAggregation() { assertEquals( - AstDSL.filteredAggregate("avg", qualifiedName("age"), - function(">", qualifiedName("age"), intLiteral(20))), - buildExprAst("avg(age) filter(where age > 20)") - ); + AstDSL.filteredAggregate( + "avg", qualifiedName("age"), function(">", qualifiedName("age"), intLiteral(20))), + buildExprAst("avg(age) filter(where age > 20)")); } @Test public void canBuildVarSamp() { - assertEquals( - aggregate("var_samp", qualifiedName("age")), - buildExprAst("var_samp(age)")); + assertEquals(aggregate("var_samp", qualifiedName("age")), buildExprAst("var_samp(age)")); } @Test public void canBuildVarPop() { - assertEquals( - aggregate("var_pop", qualifiedName("age")), - buildExprAst("var_pop(age)")); + assertEquals(aggregate("var_pop", qualifiedName("age")), buildExprAst("var_pop(age)")); } @Test public void canBuildVariance() { - assertEquals( - aggregate("variance", qualifiedName("age")), - buildExprAst("variance(age)")); + assertEquals(aggregate("variance", qualifiedName("age")), buildExprAst("variance(age)")); } @Test public void distinctCount() { assertEquals( AstDSL.distinctAggregate("count", qualifiedName("name")), - buildExprAst("count(distinct name)") - ); + buildExprAst("count(distinct name)")); } @Test public void filteredDistinctCount() { assertEquals( - AstDSL.filteredDistinctCount("count", qualifiedName("name"), function( - ">", qualifiedName("age"), intLiteral(30))), - buildExprAst("count(distinct name) filter(where age > 30)") - ); + AstDSL.filteredDistinctCount( + "count", qualifiedName("name"), function(">", qualifiedName("age"), intLiteral(30))), + buildExprAst("count(distinct name) filter(where age > 30)")); } @Test public void matchPhraseQueryAllParameters() { assertEquals( - AstDSL.function("matchphrasequery", + AstDSL.function( + "matchphrasequery", unresolvedArg("field", qualifiedName("test")), unresolvedArg("query", stringLiteral("search query")), unresolvedArg("slop", stringLiteral("3")), unresolvedArg("analyzer", stringLiteral("standard")), - unresolvedArg("zero_terms_query", stringLiteral("NONE")) - ), - buildExprAst("matchphrasequery(test, 'search query', slop = 3" - + ", analyzer = 'standard', zero_terms_query='NONE'" - + ")") - ); + unresolvedArg("zero_terms_query", stringLiteral("NONE"))), + buildExprAst( + "matchphrasequery(test, 'search query', slop = 3" + + ", analyzer = 'standard', zero_terms_query='NONE'" + + ")")); } @Test public void matchPhrasePrefixAllParameters() { assertEquals( - AstDSL.function("match_phrase_prefix", - unresolvedArg("field", qualifiedName("test")), - unresolvedArg("query", stringLiteral("search query")), - unresolvedArg("slop", stringLiteral("3")), - unresolvedArg("boost", stringLiteral("1.5")), - unresolvedArg("analyzer", stringLiteral("standard")), - unresolvedArg("max_expansions", stringLiteral("4")), - unresolvedArg("zero_terms_query", stringLiteral("NONE")) - ), - buildExprAst("match_phrase_prefix(test, 'search query', slop = 3, boost = 1.5" - + ", analyzer = 'standard', max_expansions = 4, zero_terms_query='NONE'" - + ")") - ); + AstDSL.function( + "match_phrase_prefix", + unresolvedArg("field", qualifiedName("test")), + unresolvedArg("query", stringLiteral("search query")), + unresolvedArg("slop", stringLiteral("3")), + unresolvedArg("boost", stringLiteral("1.5")), + unresolvedArg("analyzer", stringLiteral("standard")), + unresolvedArg("max_expansions", stringLiteral("4")), + unresolvedArg("zero_terms_query", stringLiteral("NONE"))), + buildExprAst( + "match_phrase_prefix(test, 'search query', slop = 3, boost = 1.5" + + ", analyzer = 'standard', max_expansions = 4, zero_terms_query='NONE'" + + ")")); } @Test public void relevanceMatch() { - assertEquals(AstDSL.function("match", - unresolvedArg("field", qualifiedName("message")), - unresolvedArg("query", stringLiteral("search query"))), - buildExprAst("match('message', 'search query')") - ); - - assertEquals(AstDSL.function("match", - unresolvedArg("field", qualifiedName("message")), - unresolvedArg("query", stringLiteral("search query")), - unresolvedArg("analyzer", stringLiteral("keyword")), - unresolvedArg("operator", stringLiteral("AND"))), + assertEquals( + AstDSL.function( + "match", + unresolvedArg("field", qualifiedName("message")), + unresolvedArg("query", stringLiteral("search query"))), + buildExprAst("match('message', 'search query')")); + + assertEquals( + AstDSL.function( + "match", + unresolvedArg("field", qualifiedName("message")), + unresolvedArg("query", stringLiteral("search query")), + unresolvedArg("analyzer", stringLiteral("keyword")), + unresolvedArg("operator", stringLiteral("AND"))), buildExprAst("match('message', 'search query', analyzer='keyword', operator='AND')")); } @Test public void relevanceMatchQuery() { - assertEquals(AstDSL.function("matchquery", + assertEquals( + AstDSL.function( + "matchquery", unresolvedArg("field", qualifiedName("message")), unresolvedArg("query", stringLiteral("search query"))), - buildExprAst("matchquery('message', 'search query')") - ); + buildExprAst("matchquery('message', 'search query')")); - assertEquals(AstDSL.function("matchquery", + assertEquals( + AstDSL.function( + "matchquery", unresolvedArg("field", qualifiedName("message")), unresolvedArg("query", stringLiteral("search query")), unresolvedArg("analyzer", stringLiteral("keyword")), @@ -615,13 +482,16 @@ public void relevanceMatchQuery() { @Test public void relevanceMatch_Query() { - assertEquals(AstDSL.function("match_query", + assertEquals( + AstDSL.function( + "match_query", unresolvedArg("field", qualifiedName("message")), unresolvedArg("query", stringLiteral("search query"))), - buildExprAst("match_query('message', 'search query')") - ); + buildExprAst("match_query('message', 'search query')")); - assertEquals(AstDSL.function("match_query", + assertEquals( + AstDSL.function( + "match_query", unresolvedArg("field", qualifiedName("message")), unresolvedArg("query", stringLiteral("search query")), unresolvedArg("analyzer", stringLiteral("keyword")), @@ -631,238 +501,279 @@ public void relevanceMatch_Query() { @Test public void relevanceMatchQueryAltSyntax() { - assertEquals(AstDSL.function("match_query", - unresolvedArg("field", stringLiteral("message")), - unresolvedArg("query", stringLiteral("search query"))).toString(), - buildExprAst("message = match_query('search query')").toString() - ); + assertEquals( + AstDSL.function( + "match_query", + unresolvedArg("field", stringLiteral("message")), + unresolvedArg("query", stringLiteral("search query"))) + .toString(), + buildExprAst("message = match_query('search query')").toString()); - assertEquals(AstDSL.function("match_query", - unresolvedArg("field", stringLiteral("message")), - unresolvedArg("query", stringLiteral("search query"))).toString(), - buildExprAst("message = match_query(\"search query\")").toString() - ); + assertEquals( + AstDSL.function( + "match_query", + unresolvedArg("field", stringLiteral("message")), + unresolvedArg("query", stringLiteral("search query"))) + .toString(), + buildExprAst("message = match_query(\"search query\")").toString()); - assertEquals(AstDSL.function("matchquery", - unresolvedArg("field", stringLiteral("message")), - unresolvedArg("query", stringLiteral("search query"))).toString(), - buildExprAst("message = matchquery('search query')").toString() - ); + assertEquals( + AstDSL.function( + "matchquery", + unresolvedArg("field", stringLiteral("message")), + unresolvedArg("query", stringLiteral("search query"))) + .toString(), + buildExprAst("message = matchquery('search query')").toString()); - assertEquals(AstDSL.function("matchquery", - unresolvedArg("field", stringLiteral("message")), - unresolvedArg("query", stringLiteral("search query"))).toString(), - buildExprAst("message = matchquery(\"search query\")").toString() - ); + assertEquals( + AstDSL.function( + "matchquery", + unresolvedArg("field", stringLiteral("message")), + unresolvedArg("query", stringLiteral("search query"))) + .toString(), + buildExprAst("message = matchquery(\"search query\")").toString()); } @Test public void relevanceMatchPhraseAltSyntax() { - assertEquals(AstDSL.function("match_phrase", - unresolvedArg("field", stringLiteral("message")), - unresolvedArg("query", stringLiteral("search query"))).toString(), - buildExprAst("message = match_phrase('search query')").toString() - ); + assertEquals( + AstDSL.function( + "match_phrase", + unresolvedArg("field", stringLiteral("message")), + unresolvedArg("query", stringLiteral("search query"))) + .toString(), + buildExprAst("message = match_phrase('search query')").toString()); - assertEquals(AstDSL.function("match_phrase", - unresolvedArg("field", stringLiteral("message")), - unresolvedArg("query", stringLiteral("search query"))).toString(), - buildExprAst("message = match_phrase(\"search query\")").toString() - ); + assertEquals( + AstDSL.function( + "match_phrase", + unresolvedArg("field", stringLiteral("message")), + unresolvedArg("query", stringLiteral("search query"))) + .toString(), + buildExprAst("message = match_phrase(\"search query\")").toString()); - assertEquals(AstDSL.function("matchphrase", - unresolvedArg("field", stringLiteral("message")), - unresolvedArg("query", stringLiteral("search query"))).toString(), - buildExprAst("message = matchphrase('search query')").toString() - ); + assertEquals( + AstDSL.function( + "matchphrase", + unresolvedArg("field", stringLiteral("message")), + unresolvedArg("query", stringLiteral("search query"))) + .toString(), + buildExprAst("message = matchphrase('search query')").toString()); - assertEquals(AstDSL.function("matchphrase", - unresolvedArg("field", stringLiteral("message")), - unresolvedArg("query", stringLiteral("search query"))).toString(), - buildExprAst("message = matchphrase(\"search query\")").toString() - ); + assertEquals( + AstDSL.function( + "matchphrase", + unresolvedArg("field", stringLiteral("message")), + unresolvedArg("query", stringLiteral("search query"))) + .toString(), + buildExprAst("message = matchphrase(\"search query\")").toString()); } @Test public void relevanceMultiMatchAltSyntax() { - assertEquals(AstDSL.function("multi_match", + assertEquals( + AstDSL.function( + "multi_match", unresolvedArg("fields", new RelevanceFieldList(ImmutableMap.of("field1", 1.F))), unresolvedArg("query", stringLiteral("search query"))), - buildExprAst("field1 = multi_match('search query')") - ); + buildExprAst("field1 = multi_match('search query')")); - assertEquals(AstDSL.function("multi_match", + assertEquals( + AstDSL.function( + "multi_match", unresolvedArg("fields", new RelevanceFieldList(ImmutableMap.of("field1", 1.F))), unresolvedArg("query", stringLiteral("search query"))), - buildExprAst("field1 = multi_match(\"search query\")") - ); + buildExprAst("field1 = multi_match(\"search query\")")); - assertEquals(AstDSL.function("multimatch", + assertEquals( + AstDSL.function( + "multimatch", unresolvedArg("fields", new RelevanceFieldList(ImmutableMap.of("field1", 1.F))), unresolvedArg("query", stringLiteral("search query"))), - buildExprAst("field1 = multimatch('search query')") - ); + buildExprAst("field1 = multimatch('search query')")); - assertEquals(AstDSL.function("multimatch", + assertEquals( + AstDSL.function( + "multimatch", unresolvedArg("fields", new RelevanceFieldList(ImmutableMap.of("field1", 1.F))), unresolvedArg("query", stringLiteral("search query"))), - buildExprAst("field1 = multimatch(\"search query\")") - ); + buildExprAst("field1 = multimatch(\"search query\")")); } @Test public void relevanceMulti_match() { - assertEquals(AstDSL.function("multi_match", - unresolvedArg("fields", new RelevanceFieldList(ImmutableMap.of( - "field2", 3.2F, "field1", 1.F))), + assertEquals( + AstDSL.function( + "multi_match", + unresolvedArg( + "fields", new RelevanceFieldList(ImmutableMap.of("field2", 3.2F, "field1", 1.F))), unresolvedArg("query", stringLiteral("search query"))), - buildExprAst("multi_match(['field1', 'field2' ^ 3.2], 'search query')") - ); + buildExprAst("multi_match(['field1', 'field2' ^ 3.2], 'search query')")); - assertEquals(AstDSL.function("multi_match", - unresolvedArg("fields", new RelevanceFieldList(ImmutableMap.of( - "field2", 3.2F, "field1", 1.F))), + assertEquals( + AstDSL.function( + "multi_match", + unresolvedArg( + "fields", new RelevanceFieldList(ImmutableMap.of("field2", 3.2F, "field1", 1.F))), unresolvedArg("query", stringLiteral("search query")), unresolvedArg("analyzer", stringLiteral("keyword")), unresolvedArg("operator", stringLiteral("AND"))), - buildExprAst("multi_match(['field1', 'field2' ^ 3.2], 'search query'," - + "analyzer='keyword', 'operator'='AND')")); + buildExprAst( + "multi_match(['field1', 'field2' ^ 3.2], 'search query'," + + "analyzer='keyword', 'operator'='AND')")); } @Test public void relevanceMultimatch_alternate_parameter_syntax() { - assertEquals(AstDSL.function("multimatch", - unresolvedArg("fields", new RelevanceFieldList(ImmutableMap.of( - "field1", 1F, "field2", 2F))), + assertEquals( + AstDSL.function( + "multimatch", + unresolvedArg( + "fields", new RelevanceFieldList(ImmutableMap.of("field1", 1F, "field2", 2F))), unresolvedArg("query", stringLiteral("search query"))), - buildExprAst("multimatch(query='search query', fields=['field1^1.0,field2^2.0'])") - ); + buildExprAst("multimatch(query='search query', fields=['field1^1.0,field2^2.0'])")); - assertEquals(AstDSL.function("multimatch", - unresolvedArg("fields", new RelevanceFieldList(ImmutableMap.of( - "field1", 1F, "field2", 2F))), + assertEquals( + AstDSL.function( + "multimatch", + unresolvedArg( + "fields", new RelevanceFieldList(ImmutableMap.of("field1", 1F, "field2", 2F))), unresolvedArg("query", stringLiteral("search query")), unresolvedArg("analyzer", stringLiteral("keyword")), unresolvedArg("operator", stringLiteral("AND"))), - buildExprAst("multimatch(query='search query', fields=['field1^1.0,field2^2.0']," - + "analyzer='keyword', operator='AND')")); + buildExprAst( + "multimatch(query='search query', fields=['field1^1.0,field2^2.0']," + + "analyzer='keyword', operator='AND')")); } @Test public void relevanceMultimatchquery_alternate_parameter_syntax() { - assertEquals(AstDSL.function("multimatchquery", - unresolvedArg("fields", new RelevanceFieldList(ImmutableMap.of( - "field", 1F))), + assertEquals( + AstDSL.function( + "multimatchquery", + unresolvedArg("fields", new RelevanceFieldList(ImmutableMap.of("field", 1F))), unresolvedArg("query", stringLiteral("search query"))), - buildExprAst("multimatchquery(query='search query', fields='field')") - ); + buildExprAst("multimatchquery(query='search query', fields='field')")); - assertEquals(AstDSL.function("multimatchquery", - unresolvedArg("fields", new RelevanceFieldList(ImmutableMap.of( - "field", 1F))), + assertEquals( + AstDSL.function( + "multimatchquery", + unresolvedArg("fields", new RelevanceFieldList(ImmutableMap.of("field", 1F))), unresolvedArg("query", stringLiteral("search query")), unresolvedArg("analyzer", stringLiteral("keyword")), unresolvedArg("operator", stringLiteral("AND"))), - buildExprAst("multimatchquery(query='search query', fields='field'," - + "analyzer='keyword', 'operator'='AND')")); + buildExprAst( + "multimatchquery(query='search query', fields='field'," + + "analyzer='keyword', 'operator'='AND')")); } @Test public void relevanceSimple_query_string() { - assertEquals(AstDSL.function("simple_query_string", - unresolvedArg("fields", new RelevanceFieldList(ImmutableMap.of( - "field2", 3.2F, "field1", 1.F))), + assertEquals( + AstDSL.function( + "simple_query_string", + unresolvedArg( + "fields", new RelevanceFieldList(ImmutableMap.of("field2", 3.2F, "field1", 1.F))), unresolvedArg("query", stringLiteral("search query"))), - buildExprAst("simple_query_string(['field1', 'field2' ^ 3.2], 'search query')") - ); + buildExprAst("simple_query_string(['field1', 'field2' ^ 3.2], 'search query')")); - assertEquals(AstDSL.function("simple_query_string", - unresolvedArg("fields", new RelevanceFieldList(ImmutableMap.of( - "field2", 3.2F, "field1", 1.F))), + assertEquals( + AstDSL.function( + "simple_query_string", + unresolvedArg( + "fields", new RelevanceFieldList(ImmutableMap.of("field2", 3.2F, "field1", 1.F))), unresolvedArg("query", stringLiteral("search query")), unresolvedArg("analyzer", stringLiteral("keyword")), unresolvedArg("operator", stringLiteral("AND"))), - buildExprAst("simple_query_string(['field1', 'field2' ^ 3.2], 'search query'," - + "analyzer='keyword', operator='AND')")); + buildExprAst( + "simple_query_string(['field1', 'field2' ^ 3.2], 'search query'," + + "analyzer='keyword', operator='AND')")); } @Test public void relevanceQuery_string() { - assertEquals(AstDSL.function("query_string", - unresolvedArg("fields", new RelevanceFieldList(ImmutableMap.of( - "field2", 3.2F, "field1", 1.F))), + assertEquals( + AstDSL.function( + "query_string", + unresolvedArg( + "fields", new RelevanceFieldList(ImmutableMap.of("field2", 3.2F, "field1", 1.F))), unresolvedArg("query", stringLiteral("search query"))), - buildExprAst("query_string(['field1', 'field2' ^ 3.2], 'search query')") - ); + buildExprAst("query_string(['field1', 'field2' ^ 3.2], 'search query')")); - assertEquals(AstDSL.function("query_string", - unresolvedArg("fields", new RelevanceFieldList(ImmutableMap.of( - "field2", 3.2F, "field1", 1.F))), + assertEquals( + AstDSL.function( + "query_string", + unresolvedArg( + "fields", new RelevanceFieldList(ImmutableMap.of("field2", 3.2F, "field1", 1.F))), unresolvedArg("query", stringLiteral("search query")), unresolvedArg("analyzer", stringLiteral("keyword")), unresolvedArg("time_zone", stringLiteral("Canada/Pacific")), unresolvedArg("tie_breaker", stringLiteral("1.3"))), - buildExprAst("query_string(['field1', 'field2' ^ 3.2], 'search query'," - + "analyzer='keyword', time_zone='Canada/Pacific', tie_breaker='1.3')")); + buildExprAst( + "query_string(['field1', 'field2' ^ 3.2], 'search query'," + + "analyzer='keyword', time_zone='Canada/Pacific', tie_breaker='1.3')")); } @Test public void relevanceWildcard_query() { - assertEquals(AstDSL.function("wildcard_query", + assertEquals( + AstDSL.function( + "wildcard_query", unresolvedArg("field", qualifiedName("field")), unresolvedArg("query", stringLiteral("search query*")), unresolvedArg("boost", stringLiteral("1.5")), unresolvedArg("case_insensitive", stringLiteral("true")), unresolvedArg("rewrite", stringLiteral("scoring_boolean"))), - buildExprAst("wildcard_query(field, 'search query*', boost=1.5," - + "case_insensitive=true, rewrite='scoring_boolean'))") - ); + buildExprAst( + "wildcard_query(field, 'search query*', boost=1.5," + + "case_insensitive=true, rewrite='scoring_boolean'))")); } @Test public void relevanceScore_query() { assertEquals( AstDSL.score( - AstDSL.function("query_string", - unresolvedArg("fields", new RelevanceFieldList(ImmutableMap.of( - "field1", 1.F, "field2", 3.2F))), - unresolvedArg("query", stringLiteral("search query")) - ), - AstDSL.doubleLiteral(1.0) - ), - buildExprAst("score(query_string(['field1', 'field2' ^ 3.2], 'search query'))") - ); + AstDSL.function( + "query_string", + unresolvedArg( + "fields", + new RelevanceFieldList(ImmutableMap.of("field1", 1.F, "field2", 3.2F))), + unresolvedArg("query", stringLiteral("search query"))), + AstDSL.doubleLiteral(1.0)), + buildExprAst("score(query_string(['field1', 'field2' ^ 3.2], 'search query'))")); } @Test public void relevanceScore_withBoost_query() { assertEquals( AstDSL.score( - AstDSL.function("query_string", - unresolvedArg("fields", new RelevanceFieldList(ImmutableMap.of( - "field1", 1.F, "field2", 3.2F))), - unresolvedArg("query", stringLiteral("search query")) - ), - doubleLiteral(1.0) - ), - buildExprAst("score(query_string(['field1', 'field2' ^ 3.2], 'search query'), 1.0)") - ); + AstDSL.function( + "query_string", + unresolvedArg( + "fields", + new RelevanceFieldList(ImmutableMap.of("field1", 1.F, "field2", 3.2F))), + unresolvedArg("query", stringLiteral("search query"))), + doubleLiteral(1.0)), + buildExprAst("score(query_string(['field1', 'field2' ^ 3.2], 'search query'), 1.0)")); } @Test public void relevanceQuery() { - assertEquals(AstDSL.function("query", - unresolvedArg("query", stringLiteral("field1:query OR field2:query"))), - buildExprAst("query('field1:query OR field2:query')") - ); + assertEquals( + AstDSL.function( + "query", unresolvedArg("query", stringLiteral("field1:query OR field2:query"))), + buildExprAst("query('field1:query OR field2:query')")); - assertEquals(AstDSL.function("query", - unresolvedArg("query", stringLiteral("search query")), - unresolvedArg("analyzer", stringLiteral("keyword")), - unresolvedArg("time_zone", stringLiteral("Canada/Pacific")), - unresolvedArg("tie_breaker", stringLiteral("1.3"))), - buildExprAst("query('search query'," - + "analyzer='keyword', time_zone='Canada/Pacific', tie_breaker='1.3')")); + assertEquals( + AstDSL.function( + "query", + unresolvedArg("query", stringLiteral("search query")), + unresolvedArg("analyzer", stringLiteral("keyword")), + unresolvedArg("time_zone", stringLiteral("Canada/Pacific")), + unresolvedArg("tie_breaker", stringLiteral("1.3"))), + buildExprAst( + "query('search query'," + + "analyzer='keyword', time_zone='Canada/Pacific', tie_breaker='1.3')")); } @Test @@ -876,7 +787,8 @@ public void canBuildInClause() { buildExprAst("age not in (20, 30)")); assertEquals( - AstDSL.in(qualifiedName("age"), + AstDSL.in( + qualifiedName("age"), AstDSL.function("abs", AstDSL.intLiteral(20)), AstDSL.function("abs", AstDSL.intLiteral(30))), buildExprAst("age in (abs(20), abs(30))")); diff --git a/sql/src/test/java/org/opensearch/sql/sql/parser/AstHavingFilterBuilderTest.java b/sql/src/test/java/org/opensearch/sql/sql/parser/AstHavingFilterBuilderTest.java index 1cb1ab5f8b..b2e4c54160 100644 --- a/sql/src/test/java/org/opensearch/sql/sql/parser/AstHavingFilterBuilderTest.java +++ b/sql/src/test/java/org/opensearch/sql/sql/parser/AstHavingFilterBuilderTest.java @@ -3,7 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ - package org.opensearch.sql.sql.parser; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -30,8 +29,7 @@ @ExtendWith(MockitoExtension.class) class AstHavingFilterBuilderTest { - @Mock - private QuerySpecification querySpec; + @Mock private QuerySpecification querySpec; private AstHavingFilterBuilder builder; diff --git a/sql/src/test/java/org/opensearch/sql/sql/parser/AstNowLikeFunctionTest.java b/sql/src/test/java/org/opensearch/sql/sql/parser/AstNowLikeFunctionTest.java index 4ce2a2d3f7..639d73e419 100644 --- a/sql/src/test/java/org/opensearch/sql/sql/parser/AstNowLikeFunctionTest.java +++ b/sql/src/test/java/org/opensearch/sql/sql/parser/AstNowLikeFunctionTest.java @@ -25,32 +25,29 @@ class AstNowLikeFunctionTest extends AstBuilderTestBase { private static Stream allFunctions() { - return Stream.of("curdate", - "current_date", - "current_time", - "current_timestamp", - "curtime", - "localtimestamp", - "localtime", - "now", - "sysdate", - "utc_date", - "utc_time", - "utc_timestamp") + return Stream.of( + "curdate", + "current_date", + "current_time", + "current_timestamp", + "curtime", + "localtimestamp", + "localtime", + "now", + "sysdate", + "utc_date", + "utc_time", + "utc_timestamp") .map(Arguments::of); } private static Stream supportFsp() { - return Stream.of("sysdate") - .map(Arguments::of); + return Stream.of("sysdate").map(Arguments::of); } private static Stream supportShortcut() { - return Stream.of("current_date", - "current_time", - "current_timestamp", - "localtimestamp", - "localtime") + return Stream.of( + "current_date", "current_time", "current_timestamp", "localtimestamp", "localtime") .map(Arguments::of); } @@ -59,12 +56,7 @@ private static Stream supportShortcut() { void project_call(String name) { String call = name + "()"; assertEquals( - project( - values(emptyList()), - alias(call, function(name)) - ), - buildAST("SELECT " + call) - ); + project(values(emptyList()), alias(call, function(name))), buildAST("SELECT " + call)); } @ParameterizedTest @@ -73,29 +65,16 @@ void filter_call(String name) { String call = name + "()"; assertEquals( project( - filter( - relation("test"), - function( - "=", - qualifiedName("data"), - function(name)) - ), - AllFields.of() - ), - buildAST("SELECT * FROM test WHERE data = " + call) - ); + filter(relation("test"), function("=", qualifiedName("data"), function(name))), + AllFields.of()), + buildAST("SELECT * FROM test WHERE data = " + call)); } - @ParameterizedTest @MethodSource("supportFsp") void fsp(String name) { assertEquals( - project( - values(emptyList()), - alias(name + "(0)", function(name, intLiteral(0))) - ), - buildAST("SELECT " + name + "(0)") - ); + project(values(emptyList()), alias(name + "(0)", function(name, intLiteral(0)))), + buildAST("SELECT " + name + "(0)")); } } diff --git a/sql/src/test/java/org/opensearch/sql/sql/parser/AstQualifiedNameBuilderTest.java b/sql/src/test/java/org/opensearch/sql/sql/parser/AstQualifiedNameBuilderTest.java index 28665dd7ef..b0a7592990 100644 --- a/sql/src/test/java/org/opensearch/sql/sql/parser/AstQualifiedNameBuilderTest.java +++ b/sql/src/test/java/org/opensearch/sql/sql/parser/AstQualifiedNameBuilderTest.java @@ -3,7 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ - package org.opensearch.sql.sql.parser; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -66,9 +65,10 @@ public void functionNameCanBeUsedAsIdentifier() { void assertFunctionNameCouldBeId(String antlrFunctionName) { List functionList = - Arrays.stream(antlrFunctionName.split("\\|")).map(String::stripLeading) - .map(String::stripTrailing).collect( - Collectors.toList()); + Arrays.stream(antlrFunctionName.split("\\|")) + .map(String::stripLeading) + .map(String::stripTrailing) + .collect(Collectors.toList()); assertFalse(functionList.isEmpty()); for (String functionName : functionList) { @@ -109,5 +109,4 @@ private OpenSearchSQLParser createParser(String expr) { return parser; } } - } diff --git a/sql/src/test/java/org/opensearch/sql/sql/parser/AstSortBuilderTest.java b/sql/src/test/java/org/opensearch/sql/sql/parser/AstSortBuilderTest.java index 3c8d155e65..f72f1ba0ff 100644 --- a/sql/src/test/java/org/opensearch/sql/sql/parser/AstSortBuilderTest.java +++ b/sql/src/test/java/org/opensearch/sql/sql/parser/AstSortBuilderTest.java @@ -3,7 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ - package org.opensearch.sql.sql.parser; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -40,14 +39,11 @@ @ExtendWith(MockitoExtension.class) class AstSortBuilderTest { - @Mock - private QuerySpecification querySpec; + @Mock private QuerySpecification querySpec; - @Mock - private OrderByClauseContext orderByClause; + @Mock private OrderByClauseContext orderByClause; - @Mock - private UnresolvedPlan child; + @Mock private UnresolvedPlan child; @Test void can_build_sort_node() { @@ -56,32 +52,35 @@ void can_build_sort_node() { ImmutableMap> expects = ImmutableMap.>builder() - .put(new SortOption(null, null), - ImmutableList.of(argument("asc", booleanLiteral(true)))) - .put(new SortOption(ASC, null), - ImmutableList.of(argument("asc", booleanLiteral(true)))) - .put(new SortOption(DESC, null), + .put( + new SortOption(null, null), ImmutableList.of(argument("asc", booleanLiteral(true)))) + .put(new SortOption(ASC, null), ImmutableList.of(argument("asc", booleanLiteral(true)))) + .put( + new SortOption(DESC, null), ImmutableList.of(argument("asc", booleanLiteral(false)))) - .put(new SortOption(null, NULL_LAST), + .put( + new SortOption(null, NULL_LAST), ImmutableList.of( argument("asc", booleanLiteral(true)), argument("nullFirst", booleanLiteral(false)))) - .put(new SortOption(DESC, NULL_FIRST), + .put( + new SortOption(DESC, NULL_FIRST), ImmutableList.of( argument("asc", booleanLiteral(false)), argument("nullFirst", booleanLiteral(true)))) .build(); - expects.forEach((option, expect) -> { - when(querySpec.getOrderByOptions()).thenReturn(ImmutableList.of(option)); + expects.forEach( + (option, expect) -> { + when(querySpec.getOrderByOptions()).thenReturn(ImmutableList.of(option)); - AstSortBuilder sortBuilder = new AstSortBuilder(querySpec); - assertEquals( - new Sort( - child, // has to mock and attach child otherwise Guava ImmutableList NPE in getChild() - ImmutableList.of(field("name", expect))), - sortBuilder.visitOrderByClause(orderByClause).attach(child)); - }); + AstSortBuilder sortBuilder = new AstSortBuilder(querySpec); + assertEquals( + new Sort( + child, // has to mock and attach child otherwise Guava ImmutableList NPE in + // getChild() + ImmutableList.of(field("name", expect))), + sortBuilder.visitOrderByClause(orderByClause).attach(child)); + }); } - } diff --git a/sql/src/test/java/org/opensearch/sql/sql/parser/context/QuerySpecificationTest.java b/sql/src/test/java/org/opensearch/sql/sql/parser/context/QuerySpecificationTest.java index 2f75e89002..ed18b3e692 100644 --- a/sql/src/test/java/org/opensearch/sql/sql/parser/context/QuerySpecificationTest.java +++ b/sql/src/test/java/org/opensearch/sql/sql/parser/context/QuerySpecificationTest.java @@ -3,7 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ - package org.opensearch.sql.sql.parser.context; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -35,32 +34,27 @@ class QuerySpecificationTest { @Test void can_collect_group_by_items_in_group_by_clause() { - QuerySpecification querySpec = collect( - "SELECT name, ABS(age) FROM test GROUP BY name, ABS(age)"); + QuerySpecification querySpec = + collect("SELECT name, ABS(age) FROM test GROUP BY name, ABS(age)"); assertEquals( - ImmutableList.of( - qualifiedName("name"), - function("ABS", qualifiedName("age"))), + ImmutableList.of(qualifiedName("name"), function("ABS", qualifiedName("age"))), querySpec.getGroupByItems()); } @Test void can_collect_select_items_in_select_clause() { - QuerySpecification querySpec = collect( - "SELECT name, ABS(age) FROM test"); + QuerySpecification querySpec = collect("SELECT name, ABS(age) FROM test"); assertEquals( - ImmutableList.of( - qualifiedName("name"), - function("ABS", qualifiedName("age"))), + ImmutableList.of(qualifiedName("name"), function("ABS", qualifiedName("age"))), querySpec.getSelectItems()); } @Test void can_collect_aggregators_in_select_clause() { - QuerySpecification querySpec = collect( - "SELECT name, AVG(age), SUM(balance) FROM test GROUP BY name"); + QuerySpecification querySpec = + collect("SELECT name, AVG(age), SUM(balance) FROM test GROUP BY name"); assertEquals( ImmutableSet.of( @@ -71,29 +65,25 @@ void can_collect_aggregators_in_select_clause() { @Test void can_collect_nested_aggregators_in_select_clause() { - QuerySpecification querySpec = collect( - "SELECT name, ABS(1 + AVG(age)) FROM test GROUP BY name"); + QuerySpecification querySpec = + collect("SELECT name, ABS(1 + AVG(age)) FROM test GROUP BY name"); assertEquals( - ImmutableSet.of( - alias("AVG(age)", aggregate("AVG", qualifiedName("age")))), + ImmutableSet.of(alias("AVG(age)", aggregate("AVG", qualifiedName("age")))), querySpec.getAggregators()); } @Test void can_collect_alias_in_select_clause() { - QuerySpecification querySpec = collect( - "SELECT name AS n FROM test GROUP BY n"); + QuerySpecification querySpec = collect("SELECT name AS n FROM test GROUP BY n"); - assertEquals( - ImmutableMap.of("n", qualifiedName("name")), - querySpec.getSelectItemsByAlias()); + assertEquals(ImmutableMap.of("n", qualifiedName("name")), querySpec.getSelectItemsByAlias()); } @Test void should_deduplicate_same_aggregators() { - QuerySpecification querySpec = collect( - "SELECT AVG(age), AVG(balance), AVG(age) FROM test GROUP BY name"); + QuerySpecification querySpec = + collect("SELECT AVG(age), AVG(balance), AVG(age) FROM test GROUP BY name"); assertEquals( ImmutableSet.of( @@ -119,20 +109,24 @@ void can_collect_sort_options_in_order_by_clause() { @Test void should_skip_sort_items_in_window_function() { - assertEquals(1, - collect("SELECT name, RANK() OVER(ORDER BY age) " - + "FROM test ORDER BY name" - ).getOrderByOptions().size()); + assertEquals( + 1, + collect("SELECT name, RANK() OVER(ORDER BY age) " + "FROM test ORDER BY name") + .getOrderByOptions() + .size()); } @Test void can_collect_filtered_aggregation() { assertEquals( - ImmutableSet.of(alias("AVG(age) FILTER(WHERE age > 20)", - filteredAggregate("AVG", qualifiedName("age"), - function(">", qualifiedName("age"), intLiteral(20))))), - collect("SELECT AVG(age) FILTER(WHERE age > 20) FROM test").getAggregators() - ); + ImmutableSet.of( + alias( + "AVG(age) FILTER(WHERE age > 20)", + filteredAggregate( + "AVG", + qualifiedName("age"), + function(">", qualifiedName("age"), intLiteral(20))))), + collect("SELECT AVG(age) FILTER(WHERE age > 20) FROM test").getAggregators()); } private QuerySpecification collect(String query) { @@ -147,5 +141,4 @@ private QuerySpecificationContext parse(String query) { parser.addErrorListener(new SyntaxAnalysisErrorListener()); return parser.querySpecification(); } - }