From e8adf10ad545c0733d5ac29dc8e8b17fcc17bc72 Mon Sep 17 00:00:00 2001 From: Mitchell Gale Date: Tue, 25 Jul 2023 09:22:56 -0700 Subject: [PATCH] Applying Google Code Format to core/src/main/java/org/opensearch/sql/exception core/src/main/java/org/opensearch/sql/executor core/src/main/java/org/opensearch/sql/expression core/src/main/java/org/opensearch/sql/monitor --- .../ExpressionEvaluationException.java | 5 +- .../sql/exception/NoCursorException.java | 7 +- .../sql/exception/QueryEngineException.java | 5 +- .../sql/exception/SemanticCheckException.java | 5 +- .../UnsupportedCursorRequestException.java | 7 +- .../sql/executor/ExecutionContext.java | 7 +- .../sql/executor/ExecutionEngine.java | 36 +- .../org/opensearch/sql/executor/Explain.java | 169 +- .../org/opensearch/sql/executor/QueryId.java | 12 +- .../opensearch/sql/executor/QueryManager.java | 5 +- .../opensearch/sql/executor/QueryService.java | 43 +- .../sql/executor/execution/AbstractPlan.java | 16 +- .../sql/executor/execution/CommandPlan.java | 19 +- .../sql/executor/execution/ExplainPlan.java | 15 +- .../sql/executor/execution/QueryPlan.java | 17 +- .../executor/execution/QueryPlanFactory.java | 65 +- .../execution/StreamingQueryPlan.java | 28 +- .../pagination/CanPaginateVisitor.java | 35 +- .../sql/executor/pagination/Cursor.java | 3 +- .../executor/pagination/PlanSerializer.java | 36 +- .../sql/executor/streaming/Batch.java | 4 +- .../MicroBatchStreamingExecution.java | 12 +- .../sql/executor/streaming/Offset.java | 4 +- .../executor/streaming/StreamingSource.java | 4 +- .../org/opensearch/sql/expression/DSL.java | 148 +- .../opensearch/sql/expression/Expression.java | 29 +- .../sql/expression/ExpressionNodeVisitor.java | 20 +- .../sql/expression/FunctionExpression.java | 12 +- .../sql/expression/HighlightExpression.java | 30 +- .../sql/expression/LiteralExpression.java | 5 +- .../expression/NamedArgumentExpression.java | 4 +- .../sql/expression/NamedExpression.java | 22 +- .../sql/expression/ReferenceExpression.java | 45 +- .../aggregation/AggregationState.java | 9 +- .../expression/aggregation/Aggregator.java | 32 +- .../aggregation/AggregatorFunction.java | 153 +- .../expression/aggregation/AvgAggregator.java | 56 +- .../aggregation/CountAggregator.java | 5 +- .../expression/aggregation/MaxAggregator.java | 5 +- .../expression/aggregation/MinAggregator.java | 10 +- .../aggregation/NamedAggregator.java | 30 +- .../aggregation/StdDevAggregator.java | 24 +- .../expression/aggregation/SumAggregator.java | 13 +- .../aggregation/TakeAggregator.java | 9 +- .../aggregation/VarianceAggregator.java | 18 +- .../conditional/cases/CaseClause.java | 28 +- .../conditional/cases/WhenClause.java | 23 +- .../expression/datetime/CalendarLookup.java | 5 +- .../datetime/DateTimeFormatterUtil.java | 246 +-- .../expression/datetime/DateTimeFunction.java | 1438 +++++++++-------- .../expression/datetime/IntervalClause.java | 4 +- .../sql/expression/env/Environment.java | 19 +- .../function/BuiltinFunctionName.java | 48 +- .../function/BuiltinFunctionRepository.java | 57 +- .../function/DefaultFunctionResolver.java | 46 +- .../expression/function/FunctionBuilder.java | 7 +- .../sql/expression/function/FunctionDSL.java | 381 +++-- .../function/FunctionImplementation.java | 13 +- .../sql/expression/function/FunctionName.java | 8 +- .../function/FunctionProperties.java | 36 +- .../expression/function/FunctionResolver.java | 4 +- .../function/FunctionSignature.java | 17 +- .../function/OpenSearchFunctions.java | 57 +- .../function/RelevanceFunctionResolver.java | 26 +- .../function/SerializableBiFunction.java | 8 +- .../function/SerializableFunction.java | 4 +- .../function/SerializableNoArgFunction.java | 8 +- .../function/SerializableQuadFunction.java | 1 - .../function/SerializableTriFunction.java | 1 - .../function/TableFunctionImplementation.java | 5 +- .../arthmetic/ArithmeticFunction.java | 379 +++-- .../arthmetic/MathematicalFunction.java | 906 ++++++----- .../operator/convert/TypeCastOperator.java | 246 +-- .../predicate/BinaryPredicateOperator.java | 178 +- .../predicate/UnaryPredicateOperator.java | 84 +- .../sql/expression/parse/GrokExpression.java | 17 +- .../sql/expression/parse/ParseExpression.java | 20 +- .../expression/parse/PatternsExpression.java | 24 +- .../sql/expression/parse/RegexExpression.java | 12 +- .../sql/expression/span/SpanExpression.java | 17 +- .../expression/system/SystemFunctions.java | 25 +- .../sql/expression/text/TextFunction.java | 304 ++-- .../expression/window/WindowDefinition.java | 9 +- .../window/WindowFunctionExpression.java | 17 +- .../expression/window/WindowFunctions.java | 15 +- .../aggregation/AggregateWindowFunction.java | 6 +- .../window/frame/CurrentRowWindowFrame.java | 21 +- .../window/frame/PeerRowsWindowFrame.java | 52 +- .../expression/window/frame/WindowFrame.java | 22 +- .../window/ranking/DenseRankFunction.java | 6 +- .../window/ranking/RankFunction.java | 11 +- .../window/ranking/RankingWindowFunction.java | 30 +- .../window/ranking/RowNumberFunction.java | 2 - .../sql/monitor/AlwaysHealthyMonitor.java | 12 +- .../sql/monitor/ResourceMonitor.java | 5 +- 95 files changed, 3177 insertions(+), 2971 deletions(-) diff --git a/core/src/main/java/org/opensearch/sql/exception/ExpressionEvaluationException.java b/core/src/main/java/org/opensearch/sql/exception/ExpressionEvaluationException.java index 65ea187666..d11f6e4f9e 100644 --- a/core/src/main/java/org/opensearch/sql/exception/ExpressionEvaluationException.java +++ b/core/src/main/java/org/opensearch/sql/exception/ExpressionEvaluationException.java @@ -3,12 +3,9 @@ * SPDX-License-Identifier: Apache-2.0 */ - package org.opensearch.sql.exception; -/** - * Exception for Expression Evaluation. - */ +/** Exception for Expression Evaluation. */ public class ExpressionEvaluationException extends QueryEngineException { public ExpressionEvaluationException(String message) { super(message); diff --git a/core/src/main/java/org/opensearch/sql/exception/NoCursorException.java b/core/src/main/java/org/opensearch/sql/exception/NoCursorException.java index 9383bece57..57f75c2cb0 100644 --- a/core/src/main/java/org/opensearch/sql/exception/NoCursorException.java +++ b/core/src/main/java/org/opensearch/sql/exception/NoCursorException.java @@ -6,8 +6,7 @@ package org.opensearch.sql.exception; /** - * This should be thrown on serialization of a PhysicalPlan tree if paging is finished. - * Processing of such exception should outcome of responding no cursor to the user. + * This should be thrown on serialization of a PhysicalPlan tree if paging is finished. Processing + * of such exception should outcome of responding no cursor to the user. */ -public class NoCursorException extends RuntimeException { -} +public class NoCursorException extends RuntimeException {} diff --git a/core/src/main/java/org/opensearch/sql/exception/QueryEngineException.java b/core/src/main/java/org/opensearch/sql/exception/QueryEngineException.java index ce90ecff5c..b3d13bef71 100644 --- a/core/src/main/java/org/opensearch/sql/exception/QueryEngineException.java +++ b/core/src/main/java/org/opensearch/sql/exception/QueryEngineException.java @@ -3,12 +3,9 @@ * SPDX-License-Identifier: Apache-2.0 */ - package org.opensearch.sql.exception; -/** - * Query analysis abstract exception. - */ +/** Query analysis abstract exception. */ public class QueryEngineException extends RuntimeException { public QueryEngineException(String message) { diff --git a/core/src/main/java/org/opensearch/sql/exception/SemanticCheckException.java b/core/src/main/java/org/opensearch/sql/exception/SemanticCheckException.java index 8673dbfc3c..6e0c184af8 100644 --- a/core/src/main/java/org/opensearch/sql/exception/SemanticCheckException.java +++ b/core/src/main/java/org/opensearch/sql/exception/SemanticCheckException.java @@ -3,12 +3,9 @@ * SPDX-License-Identifier: Apache-2.0 */ - package org.opensearch.sql.exception; -/** - * Semantic Check Exception. - */ +/** Semantic Check Exception. */ public class SemanticCheckException extends QueryEngineException { public SemanticCheckException(String message) { super(message); diff --git a/core/src/main/java/org/opensearch/sql/exception/UnsupportedCursorRequestException.java b/core/src/main/java/org/opensearch/sql/exception/UnsupportedCursorRequestException.java index 6ed8e02e5f..8117304571 100644 --- a/core/src/main/java/org/opensearch/sql/exception/UnsupportedCursorRequestException.java +++ b/core/src/main/java/org/opensearch/sql/exception/UnsupportedCursorRequestException.java @@ -5,8 +5,5 @@ package org.opensearch.sql.exception; -/** - * This should be thrown by V2 engine to support fallback scenario. - */ -public class UnsupportedCursorRequestException extends RuntimeException { -} +/** This should be thrown by V2 engine to support fallback scenario. */ +public class UnsupportedCursorRequestException extends RuntimeException {} diff --git a/core/src/main/java/org/opensearch/sql/executor/ExecutionContext.java b/core/src/main/java/org/opensearch/sql/executor/ExecutionContext.java index 8a3162068f..22d14972eb 100644 --- a/core/src/main/java/org/opensearch/sql/executor/ExecutionContext.java +++ b/core/src/main/java/org/opensearch/sql/executor/ExecutionContext.java @@ -9,12 +9,9 @@ import lombok.Getter; import org.opensearch.sql.storage.split.Split; -/** - * Execution context hold planning related information. - */ +/** Execution context hold planning related information. */ public class ExecutionContext { - @Getter - private final Optional split; + @Getter private final Optional split; public ExecutionContext(Split split) { this.split = Optional.of(split); diff --git a/core/src/main/java/org/opensearch/sql/executor/ExecutionEngine.java b/core/src/main/java/org/opensearch/sql/executor/ExecutionEngine.java index 9465da22c9..02c4d4a4b8 100644 --- a/core/src/main/java/org/opensearch/sql/executor/ExecutionEngine.java +++ b/core/src/main/java/org/opensearch/sql/executor/ExecutionEngine.java @@ -3,7 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ - package org.opensearch.sql.executor; import java.util.List; @@ -17,39 +16,33 @@ import org.opensearch.sql.executor.pagination.Cursor; import org.opensearch.sql.planner.physical.PhysicalPlan; -/** - * Execution engine that encapsulates execution details. - */ +/** Execution engine that encapsulates execution details. */ public interface ExecutionEngine { /** - * Execute physical plan and call back response listener. - * Todo. deprecated this interface after finalize {@link ExecutionContext}. + * Execute physical plan and call back response listener. Todo. deprecated this interface after + * finalize {@link ExecutionContext}. * - * @param plan executable physical plan + * @param plan executable physical plan * @param listener response listener */ void execute(PhysicalPlan plan, ResponseListener listener); - /** - * Execute physical plan with {@link ExecutionContext} and call back response listener. - */ - void execute(PhysicalPlan plan, ExecutionContext context, - ResponseListener listener); + /** Execute physical plan with {@link ExecutionContext} and call back response listener. */ + void execute( + PhysicalPlan plan, ExecutionContext context, ResponseListener listener); /** - * Explain physical plan and call back response listener. The reason why this has to - * be part of execution engine interface is that the physical plan probably needs to - * be executed to get more info for profiling, such as actual execution time, rows fetched etc. + * Explain physical plan and call back response listener. The reason why this has to be part of + * execution engine interface is that the physical plan probably needs to be executed to get more + * info for profiling, such as actual execution time, rows fetched etc. * - * @param plan physical plan to explain + * @param plan physical plan to explain * @param listener response listener */ void explain(PhysicalPlan plan, ResponseListener listener); - /** - * Data class that encapsulates ExprValue. - */ + /** Data class that encapsulates ExprValue. */ @Data class QueryResponse { private final Schema schema; @@ -70,8 +63,8 @@ public static class Column { } /** - * Data class that encapsulates explain result. This can help decouple core engine - * from concrete explain response format. + * Data class that encapsulates explain result. This can help decouple core engine from concrete + * explain response format. */ @Data class ExplainResponse { @@ -86,5 +79,4 @@ class ExplainResponseNode { private Map description; private List children; } - } diff --git a/core/src/main/java/org/opensearch/sql/executor/Explain.java b/core/src/main/java/org/opensearch/sql/executor/Explain.java index 7c16e0b720..0f05b99383 100644 --- a/core/src/main/java/org/opensearch/sql/executor/Explain.java +++ b/core/src/main/java/org/opensearch/sql/executor/Explain.java @@ -3,7 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ - package org.opensearch.sql.executor; import com.google.common.collect.ImmutableMap; @@ -35,11 +34,9 @@ import org.opensearch.sql.planner.physical.WindowOperator; import org.opensearch.sql.storage.TableScanOperator; -/** - * Visitor that explains a physical plan to JSON format. - */ +/** Visitor that explains a physical plan to JSON format. */ public class Explain extends PhysicalPlanNodeVisitor - implements Function { + implements Function { @Override public ExplainResponse apply(PhysicalPlan plan) { @@ -48,109 +45,160 @@ public ExplainResponse apply(PhysicalPlan plan) { @Override public ExplainResponseNode visitProject(ProjectOperator node, Object context) { - return explain(node, context, explainNode -> explainNode.setDescription(ImmutableMap.of( - "fields", node.getProjectList().toString()))); + return explain( + node, + context, + explainNode -> + explainNode.setDescription( + ImmutableMap.of("fields", node.getProjectList().toString()))); } @Override public ExplainResponseNode visitFilter(FilterOperator node, Object context) { - return explain(node, context, explainNode -> explainNode.setDescription(ImmutableMap.of( - "conditions", node.getConditions().toString()))); + return explain( + node, + context, + explainNode -> + explainNode.setDescription( + ImmutableMap.of("conditions", node.getConditions().toString()))); } @Override public ExplainResponseNode visitSort(SortOperator node, Object context) { - return explain(node, context, explainNode -> explainNode.setDescription(ImmutableMap.of( - "sortList", describeSortList(node.getSortList())))); + return explain( + node, + context, + explainNode -> + explainNode.setDescription( + ImmutableMap.of("sortList", describeSortList(node.getSortList())))); } @Override public ExplainResponseNode visitTableScan(TableScanOperator node, Object context) { - return explain(node, context, explainNode -> explainNode.setDescription(ImmutableMap.of( - "request", node.toString()))); + return explain( + node, + context, + explainNode -> explainNode.setDescription(ImmutableMap.of("request", node.toString()))); } @Override public ExplainResponseNode visitAggregation(AggregationOperator node, Object context) { - return explain(node, context, explainNode -> explainNode.setDescription(ImmutableMap.of( - "aggregators", node.getAggregatorList().toString(), - "groupBy", node.getGroupByExprList().toString()))); + return explain( + node, + context, + explainNode -> + explainNode.setDescription( + ImmutableMap.of( + "aggregators", node.getAggregatorList().toString(), + "groupBy", node.getGroupByExprList().toString()))); } @Override public ExplainResponseNode visitWindow(WindowOperator node, Object context) { - return explain(node, context, explainNode -> explainNode.setDescription(ImmutableMap.of( - "function", node.getWindowFunction().toString(), - "definition", ImmutableMap.of( - "partitionBy", node.getWindowDefinition().getPartitionByList().toString(), - "sortList", describeSortList(node.getWindowDefinition().getSortList()))))); + return explain( + node, + context, + explainNode -> + explainNode.setDescription( + ImmutableMap.of( + "function", node.getWindowFunction().toString(), + "definition", + ImmutableMap.of( + "partitionBy", + node.getWindowDefinition().getPartitionByList().toString(), + "sortList", + describeSortList(node.getWindowDefinition().getSortList()))))); } @Override public ExplainResponseNode visitRename(RenameOperator node, Object context) { Map renameMappingDescription = - node.getMapping() - .entrySet() - .stream() - .collect(Collectors.toMap( - e -> e.getKey().toString(), - e -> e.getValue().toString())); + node.getMapping().entrySet().stream() + .collect(Collectors.toMap(e -> e.getKey().toString(), e -> e.getValue().toString())); - return explain(node, context, explainNode -> explainNode.setDescription(ImmutableMap.of( - "mapping", renameMappingDescription))); + return explain( + node, + context, + explainNode -> + explainNode.setDescription(ImmutableMap.of("mapping", renameMappingDescription))); } @Override public ExplainResponseNode visitRemove(RemoveOperator node, Object context) { - return explain(node, context, explainNode -> explainNode.setDescription(ImmutableMap.of( - "removeList", node.getRemoveList().toString()))); + return explain( + node, + context, + explainNode -> + explainNode.setDescription( + ImmutableMap.of("removeList", node.getRemoveList().toString()))); } @Override public ExplainResponseNode visitEval(EvalOperator node, Object context) { - return explain(node, context, explainNode -> explainNode.setDescription(ImmutableMap.of( - "expressions", convertPairListToMap(node.getExpressionList())))); + return explain( + node, + context, + explainNode -> + explainNode.setDescription( + ImmutableMap.of("expressions", convertPairListToMap(node.getExpressionList())))); } @Override public ExplainResponseNode visitDedupe(DedupeOperator node, Object context) { - return explain(node, context, explainNode -> explainNode.setDescription(ImmutableMap.of( - "dedupeList", node.getDedupeList().toString(), - "allowedDuplication", node.getAllowedDuplication(), - "keepEmpty", node.getKeepEmpty(), - "consecutive", node.getConsecutive()))); + return explain( + node, + context, + explainNode -> + explainNode.setDescription( + ImmutableMap.of( + "dedupeList", node.getDedupeList().toString(), + "allowedDuplication", node.getAllowedDuplication(), + "keepEmpty", node.getKeepEmpty(), + "consecutive", node.getConsecutive()))); } @Override public ExplainResponseNode visitRareTopN(RareTopNOperator node, Object context) { - return explain(node, context, explainNode -> explainNode.setDescription(ImmutableMap.of( - "commandType", node.getCommandType(), - "noOfResults", node.getNoOfResults(), - "fields", node.getFieldExprList().toString(), - "groupBy", node.getGroupByExprList().toString() - ))); + return explain( + node, + context, + explainNode -> + explainNode.setDescription( + ImmutableMap.of( + "commandType", node.getCommandType(), + "noOfResults", node.getNoOfResults(), + "fields", node.getFieldExprList().toString(), + "groupBy", node.getGroupByExprList().toString()))); } @Override public ExplainResponseNode visitValues(ValuesOperator node, Object context) { - return explain(node, context, explainNode -> explainNode.setDescription(ImmutableMap.of( - "values", node.getValues()))); + return explain( + node, + context, + explainNode -> explainNode.setDescription(ImmutableMap.of("values", node.getValues()))); } @Override public ExplainResponseNode visitLimit(LimitOperator node, Object context) { - return explain(node, context, explanNode -> explanNode.setDescription(ImmutableMap.of( - "limit", node.getLimit(), "offset", node.getOffset()))); + return explain( + node, + context, + explanNode -> + explanNode.setDescription( + ImmutableMap.of("limit", node.getLimit(), "offset", node.getOffset()))); } @Override public ExplainResponseNode visitNested(NestedOperator node, Object context) { - return explain(node, context, explanNode -> explanNode.setDescription(ImmutableMap.of( - "nested", node.getFields()))); + return explain( + node, + context, + explanNode -> explanNode.setDescription(ImmutableMap.of("nested", node.getFields()))); } - protected ExplainResponseNode explain(PhysicalPlan node, Object context, - Consumer doExplain) { + protected ExplainResponseNode explain( + PhysicalPlan node, Object context, Consumer doExplain) { ExplainResponseNode explainNode = new ExplainResponseNode(getOperatorName(node)); List children = new ArrayList<>(); @@ -169,19 +217,18 @@ private String getOperatorName(PhysicalPlan node) { private Map convertPairListToMap(List> pairs) { return pairs.stream() - .collect(Collectors.toMap( - p -> p.getLeft().toString(), - p -> p.getRight().toString())); + .collect(Collectors.toMap(p -> p.getLeft().toString(), p -> p.getRight().toString())); } private Map> describeSortList( List> sortList) { return sortList.stream() - .collect(Collectors.toMap( - p -> p.getRight().toString(), - p -> ImmutableMap.of( - "sortOrder", p.getLeft().getSortOrder().toString(), - "nullOrder", p.getLeft().getNullOrder().toString()))); + .collect( + Collectors.toMap( + p -> p.getRight().toString(), + p -> + ImmutableMap.of( + "sortOrder", p.getLeft().getSortOrder().toString(), + "nullOrder", p.getLeft().getNullOrder().toString()))); } - } diff --git a/core/src/main/java/org/opensearch/sql/executor/QueryId.java b/core/src/main/java/org/opensearch/sql/executor/QueryId.java index 933cb5d82d..eea8166e2a 100644 --- a/core/src/main/java/org/opensearch/sql/executor/QueryId.java +++ b/core/src/main/java/org/opensearch/sql/executor/QueryId.java @@ -12,18 +12,14 @@ import org.apache.commons.lang3.RandomStringUtils; import org.opensearch.sql.executor.execution.AbstractPlan; -/** - * Query id of {@link AbstractPlan}. - */ +/** Query id of {@link AbstractPlan}. */ public class QueryId { - /** - * Query id. - */ - @Getter - private final String queryId; + /** Query id. */ + @Getter private final String queryId; /** * Generate {@link QueryId}. + * * @return {@link QueryId}. */ public static QueryId queryId() { diff --git a/core/src/main/java/org/opensearch/sql/executor/QueryManager.java b/core/src/main/java/org/opensearch/sql/executor/QueryManager.java index 5b41d7ce2e..ed87290065 100644 --- a/core/src/main/java/org/opensearch/sql/executor/QueryManager.java +++ b/core/src/main/java/org/opensearch/sql/executor/QueryManager.java @@ -11,13 +11,14 @@ import org.opensearch.sql.executor.execution.AbstractPlan; /** - * QueryManager is the high-level interface of core engine. - * Frontend submit {@link AbstractPlan} to QueryManager. + * QueryManager is the high-level interface of core engine. Frontend submit {@link AbstractPlan} to + * QueryManager. */ public interface QueryManager { /** * Submit {@link AbstractPlan}. + * * @param queryPlan {@link AbstractPlan}. * @return {@link QueryId}. */ diff --git a/core/src/main/java/org/opensearch/sql/executor/QueryService.java b/core/src/main/java/org/opensearch/sql/executor/QueryService.java index 94e7081920..e71ad81c25 100644 --- a/core/src/main/java/org/opensearch/sql/executor/QueryService.java +++ b/core/src/main/java/org/opensearch/sql/executor/QueryService.java @@ -18,9 +18,7 @@ import org.opensearch.sql.planner.logical.LogicalPlan; import org.opensearch.sql.planner.physical.PhysicalPlan; -/** - * The low level interface of core engine. - */ +/** The low level interface of core engine. */ @RequiredArgsConstructor public class QueryService { @@ -31,14 +29,14 @@ public class QueryService { private final Planner planner; /** - * Execute the {@link UnresolvedPlan}, using {@link ResponseListener} to get response. - * Todo. deprecated this interface after finalize {@link PlanContext}. + * Execute the {@link UnresolvedPlan}, using {@link ResponseListener} to get response. Todo. + * deprecated this interface after finalize {@link PlanContext}. * - * @param plan {@link UnresolvedPlan} + * @param plan {@link UnresolvedPlan} * @param listener {@link ResponseListener} */ - public void execute(UnresolvedPlan plan, - ResponseListener listener) { + public void execute( + UnresolvedPlan plan, ResponseListener listener) { try { executePlan(analyze(plan), PlanContext.emptyPlanContext(), listener); } catch (Exception e) { @@ -48,22 +46,23 @@ public void execute(UnresolvedPlan plan, /** * Execute the {@link UnresolvedPlan}, with {@link PlanContext} and using {@link ResponseListener} - * to get response. - * Todo. Pass split from PlanContext to ExecutionEngine in following PR. + * to get response. Todo. Pass split from PlanContext to ExecutionEngine in following PR. * * @param plan {@link LogicalPlan} * @param planContext {@link PlanContext} * @param listener {@link ResponseListener} */ - public void executePlan(LogicalPlan plan, - PlanContext planContext, - ResponseListener listener) { + public void executePlan( + LogicalPlan plan, + PlanContext planContext, + ResponseListener listener) { try { planContext .getSplit() .ifPresentOrElse( split -> executionEngine.execute(plan(plan), new ExecutionContext(split), listener), - () -> executionEngine.execute( + () -> + executionEngine.execute( plan(plan), ExecutionContext.emptyExecutionContext(), listener)); } catch (Exception e) { listener.onFailure(e); @@ -71,14 +70,14 @@ public void executePlan(LogicalPlan plan, } /** - * Explain the query in {@link UnresolvedPlan} using {@link ResponseListener} to - * get and format explain response. + * Explain the query in {@link UnresolvedPlan} using {@link ResponseListener} to get and format + * explain response. * * @param plan {@link UnresolvedPlan} * @param listener {@link ResponseListener} for explain response */ - public void explain(UnresolvedPlan plan, - ResponseListener listener) { + public void explain( + UnresolvedPlan plan, ResponseListener listener) { try { executionEngine.explain(plan(analyze(plan)), listener); } catch (Exception e) { @@ -86,16 +85,12 @@ public void explain(UnresolvedPlan plan, } } - /** - * Analyze {@link UnresolvedPlan}. - */ + /** Analyze {@link UnresolvedPlan}. */ public LogicalPlan analyze(UnresolvedPlan plan) { return analyzer.analyze(plan, new AnalysisContext()); } - /** - * Translate {@link LogicalPlan} to {@link PhysicalPlan}. - */ + /** Translate {@link LogicalPlan} to {@link PhysicalPlan}. */ public PhysicalPlan plan(LogicalPlan plan) { return planner.plan(plan); } diff --git a/core/src/main/java/org/opensearch/sql/executor/execution/AbstractPlan.java b/core/src/main/java/org/opensearch/sql/executor/execution/AbstractPlan.java index 1654293c04..23091777ce 100644 --- a/core/src/main/java/org/opensearch/sql/executor/execution/AbstractPlan.java +++ b/core/src/main/java/org/opensearch/sql/executor/execution/AbstractPlan.java @@ -8,28 +8,20 @@ package org.opensearch.sql.executor.execution; - import lombok.Getter; import lombok.RequiredArgsConstructor; import org.opensearch.sql.common.response.ResponseListener; import org.opensearch.sql.executor.ExecutionEngine; import org.opensearch.sql.executor.QueryId; -/** - * AbstractPlan represent the execution entity of the Statement. - */ +/** AbstractPlan represent the execution entity of the Statement. */ @RequiredArgsConstructor public abstract class AbstractPlan { - /** - * Uniq query id. - */ - @Getter - private final QueryId queryId; + /** Uniq query id. */ + @Getter private final QueryId queryId; - /** - * Start query execution. - */ + /** Start query execution. */ public abstract void execute(); /** diff --git a/core/src/main/java/org/opensearch/sql/executor/execution/CommandPlan.java b/core/src/main/java/org/opensearch/sql/executor/execution/CommandPlan.java index 0ea5266084..103e0e1081 100644 --- a/core/src/main/java/org/opensearch/sql/executor/execution/CommandPlan.java +++ b/core/src/main/java/org/opensearch/sql/executor/execution/CommandPlan.java @@ -15,26 +15,25 @@ import org.opensearch.sql.executor.QueryService; /** - * Query plan which does not reflect a search query being executed. - * It contains a command or an action, for example, a DDL query. + * Query plan which does not reflect a search query being executed. It contains a command or an + * action, for example, a DDL query. */ public class CommandPlan extends AbstractPlan { - /** - * The query plan ast. - */ + /** The query plan ast. */ protected final UnresolvedPlan plan; - /** - * Query service. - */ + /** Query service. */ protected final QueryService queryService; protected final ResponseListener listener; /** Constructor. */ - public CommandPlan(QueryId queryId, UnresolvedPlan plan, QueryService queryService, - ResponseListener listener) { + public CommandPlan( + QueryId queryId, + UnresolvedPlan plan, + QueryService queryService, + ResponseListener listener) { super(queryId); this.plan = plan; this.queryService = queryService; diff --git a/core/src/main/java/org/opensearch/sql/executor/execution/ExplainPlan.java b/core/src/main/java/org/opensearch/sql/executor/execution/ExplainPlan.java index 8c784f82ed..7868a39001 100644 --- a/core/src/main/java/org/opensearch/sql/executor/execution/ExplainPlan.java +++ b/core/src/main/java/org/opensearch/sql/executor/execution/ExplainPlan.java @@ -12,21 +12,18 @@ import org.opensearch.sql.executor.ExecutionEngine; import org.opensearch.sql.executor.QueryId; -/** - * Explain plan. - */ +/** Explain plan. */ public class ExplainPlan extends AbstractPlan { private final AbstractPlan plan; private final ResponseListener explainListener; - /** - * Constructor. - */ - public ExplainPlan(QueryId queryId, - AbstractPlan plan, - ResponseListener explainListener) { + /** Constructor. */ + public ExplainPlan( + QueryId queryId, + AbstractPlan plan, + ResponseListener explainListener) { super(queryId); this.plan = plan; this.explainListener = explainListener; diff --git a/core/src/main/java/org/opensearch/sql/executor/execution/QueryPlan.java b/core/src/main/java/org/opensearch/sql/executor/execution/QueryPlan.java index aeecf3e76f..0ebdb875f6 100644 --- a/core/src/main/java/org/opensearch/sql/executor/execution/QueryPlan.java +++ b/core/src/main/java/org/opensearch/sql/executor/execution/QueryPlan.java @@ -17,19 +17,13 @@ import org.opensearch.sql.executor.QueryId; import org.opensearch.sql.executor.QueryService; -/** - * Query plan which includes a select query. - */ +/** Query plan which includes a select query. */ public class QueryPlan extends AbstractPlan { - /** - * The query plan ast. - */ + /** The query plan ast. */ protected final UnresolvedPlan plan; - /** - * Query service. - */ + /** Query service. */ protected final QueryService queryService; protected final ResponseListener listener; @@ -75,8 +69,9 @@ public void execute() { @Override public void explain(ResponseListener listener) { if (pageSize.isPresent()) { - listener.onFailure(new NotImplementedException( - "`explain` feature for paginated requests is not implemented yet.")); + listener.onFailure( + new NotImplementedException( + "`explain` feature for paginated requests is not implemented yet.")); } else { queryService.explain(plan, listener); } diff --git a/core/src/main/java/org/opensearch/sql/executor/execution/QueryPlanFactory.java b/core/src/main/java/org/opensearch/sql/executor/execution/QueryPlanFactory.java index 3273eb3c18..52d7126e17 100644 --- a/core/src/main/java/org/opensearch/sql/executor/execution/QueryPlanFactory.java +++ b/core/src/main/java/org/opensearch/sql/executor/execution/QueryPlanFactory.java @@ -27,9 +27,7 @@ import org.opensearch.sql.executor.QueryService; import org.opensearch.sql.executor.pagination.CanPaginateVisitor; -/** - * QueryExecution Factory. - */ +/** QueryExecution Factory. */ @RequiredArgsConstructor public class QueryPlanFactory extends AbstractNodeVisitor< @@ -38,14 +36,12 @@ public class QueryPlanFactory Optional>, Optional>>> { - /** - * Query Service. - */ + /** Query Service. */ private final QueryService queryService; /** - * NO_CONSUMER_RESPONSE_LISTENER should never be called. It is only used as constructor - * parameter of {@link QueryPlan}. + * NO_CONSUMER_RESPONSE_LISTENER should never be called. It is only used as constructor parameter + * of {@link QueryPlan}. */ @VisibleForTesting protected static final ResponseListener @@ -64,9 +60,7 @@ public void onFailure(Exception e) { } }; - /** - * Create QueryExecution from Statement. - */ + /** Create QueryExecution from Statement. */ public AbstractPlan create( Statement statement, Optional> queryListener, @@ -74,12 +68,12 @@ public AbstractPlan create( return statement.accept(this, Pair.of(queryListener, explainListener)); } - /** - * Creates a QueryPlan from a cursor. - */ - public AbstractPlan create(String cursor, boolean isExplain, - ResponseListener queryResponseListener, - ResponseListener explainListener) { + /** Creates a QueryPlan from a cursor. */ + public AbstractPlan create( + String cursor, + boolean isExplain, + ResponseListener queryResponseListener, + ResponseListener explainListener) { QueryId queryId = QueryId.queryId(); var plan = new QueryPlan(queryId, new FetchCursor(cursor), queryService, queryResponseListener); return isExplain ? new ExplainPlan(queryId, plan, explainListener) : plan; @@ -89,27 +83,32 @@ boolean canConvertToCursor(UnresolvedPlan plan) { return plan.accept(new CanPaginateVisitor(), null); } - /** - * Creates a {@link CloseCursor} command on a cursor. - */ - public AbstractPlan createCloseCursor(String cursor, - ResponseListener queryResponseListener) { - return new CommandPlan(QueryId.queryId(), new CloseCursor().attach(new FetchCursor(cursor)), - queryService, queryResponseListener); + /** Creates a {@link CloseCursor} command on a cursor. */ + public AbstractPlan createCloseCursor( + String cursor, ResponseListener queryResponseListener) { + return new CommandPlan( + QueryId.queryId(), + new CloseCursor().attach(new FetchCursor(cursor)), + queryService, + queryResponseListener); } @Override public AbstractPlan visitQuery( Query node, - Pair>, - Optional>> + Pair< + Optional>, + Optional>> context) { Preconditions.checkArgument( context.getLeft().isPresent(), "[BUG] query listener must be not null"); if (node.getFetchSize() > 0) { if (canConvertToCursor(node.getPlan())) { - return new QueryPlan(QueryId.queryId(), node.getPlan(), node.getFetchSize(), + return new QueryPlan( + QueryId.queryId(), + node.getPlan(), + node.getFetchSize(), queryService, context.getLeft().get()); } else { @@ -117,24 +116,24 @@ public AbstractPlan visitQuery( throw new UnsupportedCursorRequestException(); } } else { - return new QueryPlan(QueryId.queryId(), node.getPlan(), queryService, - context.getLeft().get()); + return new QueryPlan( + QueryId.queryId(), node.getPlan(), queryService, context.getLeft().get()); } } @Override public AbstractPlan visitExplain( Explain node, - Pair>, - Optional>> + Pair< + Optional>, + Optional>> context) { Preconditions.checkArgument( context.getRight().isPresent(), "[BUG] explain listener must be not null"); return new ExplainPlan( QueryId.queryId(), - create(node.getStatement(), - Optional.of(NO_CONSUMER_RESPONSE_LISTENER), Optional.empty()), + create(node.getStatement(), Optional.of(NO_CONSUMER_RESPONSE_LISTENER), Optional.empty()), context.getRight().get()); } } diff --git a/core/src/main/java/org/opensearch/sql/executor/execution/StreamingQueryPlan.java b/core/src/main/java/org/opensearch/sql/executor/execution/StreamingQueryPlan.java index 9bb37b064c..52348319c8 100644 --- a/core/src/main/java/org/opensearch/sql/executor/execution/StreamingQueryPlan.java +++ b/core/src/main/java/org/opensearch/sql/executor/execution/StreamingQueryPlan.java @@ -24,9 +24,7 @@ import org.opensearch.sql.planner.logical.LogicalPlanNodeVisitor; import org.opensearch.sql.planner.logical.LogicalRelation; -/** - * Streaming Query Plan. - */ +/** Streaming Query Plan. */ public class StreamingQueryPlan extends QueryPlan { private static final Logger log = LogManager.getLogger(StreamingQueryPlan.class); @@ -35,14 +33,13 @@ public class StreamingQueryPlan extends QueryPlan { private MicroBatchStreamingExecution streamingExecution; - /** - * constructor. - */ - public StreamingQueryPlan(QueryId queryId, - UnresolvedPlan plan, - QueryService queryService, - ResponseListener listener, - ExecutionStrategy executionStrategy) { + /** constructor. */ + public StreamingQueryPlan( + QueryId queryId, + UnresolvedPlan plan, + QueryService queryService, + ResponseListener listener, + ExecutionStrategy executionStrategy) { super(queryId, plan, queryService, listener); this.executionStrategy = executionStrategy; @@ -70,16 +67,13 @@ public void execute() { } interface ExecutionStrategy { - /** - * execute task. - */ + /** execute task. */ void execute(Runnable task) throws InterruptedException; } /** - * execute task with fixed interval. - * if task run time < interval, trigger next task on next interval. - * if task run time >= interval, trigger next task immediately. + * execute task with fixed interval. if task run time < interval, trigger next task on next + * interval. if task run time >= interval, trigger next task immediately. */ @RequiredArgsConstructor public static class IntervalTriggerExecution implements ExecutionStrategy { diff --git a/core/src/main/java/org/opensearch/sql/executor/pagination/CanPaginateVisitor.java b/core/src/main/java/org/opensearch/sql/executor/pagination/CanPaginateVisitor.java index e304c132bd..c7ae350245 100644 --- a/core/src/main/java/org/opensearch/sql/executor/pagination/CanPaginateVisitor.java +++ b/core/src/main/java/org/opensearch/sql/executor/pagination/CanPaginateVisitor.java @@ -41,19 +41,16 @@ import org.opensearch.sql.expression.function.BuiltinFunctionName; /** - * Use this unresolved plan visitor to check if a plan can be serialized by PaginatedPlanCache. - * If
plan.accept(new CanPaginateVisitor(...))
returns true, - * then PaginatedPlanCache.convertToCursor will succeed. Otherwise, it will fail. - * The purpose of this visitor is to activate legacy engine fallback mechanism. - * Currently, V2 engine does not support queries with: - * - aggregation (GROUP BY clause or aggregation functions like min/max) - * - in memory aggregation (window function) - * - LIMIT/OFFSET clause(s) - * - without FROM clause - * - JOIN - * - a subquery - * V2 also requires that the table being queried should be an OpenSearch index. - * See PaginatedPlanCache.canConvertToCursor for usage. + * Use this unresolved plan visitor to check if a plan can be serialized by PaginatedPlanCache. If + * + *
plan.accept(new CanPaginateVisitor(...))
+ * + * returns true, then PaginatedPlanCache.convertToCursor will succeed. Otherwise, it will + * fail. The purpose of this visitor is to activate legacy engine fallback mechanism. Currently, V2 + * engine does not support queries with: - aggregation (GROUP BY clause or aggregation functions + * like min/max) - in memory aggregation (window function) - LIMIT/OFFSET clause(s) - without FROM + * clause - JOIN - a subquery V2 also requires that the table being queried should be an OpenSearch + * index. See PaginatedPlanCache.canConvertToCursor for usage. */ public class CanPaginateVisitor extends AbstractNodeVisitor { @@ -80,8 +77,8 @@ protected Boolean canPaginate(Node node, Object context) { // https://github.com/opensearch-project/sql/issues/1471 @Override public Boolean visitSort(Sort node, Object context) { - return node.getSortList().stream().allMatch(f -> f.getField() instanceof QualifiedName - && visitField(f, context)) + return node.getSortList().stream() + .allMatch(f -> f.getField() instanceof QualifiedName && visitField(f, context)) && canPaginate(node, context); } @@ -116,8 +113,8 @@ public Boolean visitLiteral(Literal node, Object context) { @Override public Boolean visitField(Field node, Object context) { - return canPaginate(node, context) && node.getFieldArgs().stream() - .allMatch(n -> n.accept(this, context)); + return canPaginate(node, context) + && node.getFieldArgs().stream().allMatch(n -> n.accept(this, context)); } @Override @@ -192,8 +189,8 @@ public Boolean visitFunction(Function node, Object context) { @Override public Boolean visitIn(In node, Object context) { - return canPaginate(node, context) && node.getValueList().stream() - .allMatch(n -> n.accept(this, context)); + return canPaginate(node, context) + && node.getValueList().stream().allMatch(n -> n.accept(this, context)); } @Override diff --git a/core/src/main/java/org/opensearch/sql/executor/pagination/Cursor.java b/core/src/main/java/org/opensearch/sql/executor/pagination/Cursor.java index bb320f5c67..59a14a2d72 100644 --- a/core/src/main/java/org/opensearch/sql/executor/pagination/Cursor.java +++ b/core/src/main/java/org/opensearch/sql/executor/pagination/Cursor.java @@ -14,8 +14,7 @@ public class Cursor { public static final Cursor None = new Cursor(null); - @Getter - private final String data; + @Getter private final String data; public String toString() { return data; diff --git a/core/src/main/java/org/opensearch/sql/executor/pagination/PlanSerializer.java b/core/src/main/java/org/opensearch/sql/executor/pagination/PlanSerializer.java index 07cf174d73..40a6cdfa84 100644 --- a/core/src/main/java/org/opensearch/sql/executor/pagination/PlanSerializer.java +++ b/core/src/main/java/org/opensearch/sql/executor/pagination/PlanSerializer.java @@ -24,8 +24,8 @@ import org.opensearch.sql.storage.StorageEngine; /** - * This class is entry point to paged requests. It is responsible to cursor serialization - * and deserialization. + * This class is entry point to paged requests. It is responsible to cursor serialization and + * deserialization. */ @RequiredArgsConstructor public class PlanSerializer { @@ -33,14 +33,11 @@ public class PlanSerializer { private final StorageEngine engine; - - /** - * Converts a physical plan tree to a cursor. - */ + /** Converts a physical plan tree to a cursor. */ public Cursor convertToCursor(PhysicalPlan plan) { try { - return new Cursor(CURSOR_PREFIX - + serialize(((SerializablePlan) plan).getPlanForSerialization())); + return new Cursor( + CURSOR_PREFIX + serialize(((SerializablePlan) plan).getPlanForSerialization())); // ClassCastException thrown when a plan in the tree doesn't implement SerializablePlan } catch (NotSerializableException | ClassCastException | NoCursorException e) { return Cursor.None; @@ -49,6 +46,7 @@ public Cursor convertToCursor(PhysicalPlan plan) { /** * Serializes and compresses the object. + * * @param object The object. * @return Encoded binary data. */ @@ -61,9 +59,12 @@ protected String serialize(Serializable object) throws NotSerializableException ByteArrayOutputStream out = new ByteArrayOutputStream(); // GZIP provides 35-45%, lzma from apache commons-compress has few % better compression - GZIPOutputStream gzip = new GZIPOutputStream(out) { { - this.def.setLevel(Deflater.BEST_COMPRESSION); - } }; + GZIPOutputStream gzip = + new GZIPOutputStream(out) { + { + this.def.setLevel(Deflater.BEST_COMPRESSION); + } + }; gzip.write(output.toByteArray()); gzip.close(); @@ -77,24 +78,23 @@ protected String serialize(Serializable object) throws NotSerializableException /** * Decompresses and deserializes the binary data. + * * @param code Encoded binary data. * @return An object. */ protected Serializable deserialize(String code) { try { - GZIPInputStream gzip = new GZIPInputStream( - new ByteArrayInputStream(HashCode.fromString(code).asBytes())); - ObjectInputStream objectInput = new CursorDeserializationStream( - new ByteArrayInputStream(gzip.readAllBytes())); + GZIPInputStream gzip = + new GZIPInputStream(new ByteArrayInputStream(HashCode.fromString(code).asBytes())); + ObjectInputStream objectInput = + new CursorDeserializationStream(new ByteArrayInputStream(gzip.readAllBytes())); return (Serializable) objectInput.readObject(); } catch (Exception e) { throw new IllegalStateException("Failed to deserialize object", e); } } - /** - * Converts a cursor to a physical plan tree. - */ + /** Converts a cursor to a physical plan tree. */ public PhysicalPlan convertToPlan(String cursor) { if (!cursor.startsWith(CURSOR_PREFIX)) { throw new UnsupportedOperationException("Unsupported cursor"); diff --git a/core/src/main/java/org/opensearch/sql/executor/streaming/Batch.java b/core/src/main/java/org/opensearch/sql/executor/streaming/Batch.java index cd7d7dae5a..ab03c4fb53 100644 --- a/core/src/main/java/org/opensearch/sql/executor/streaming/Batch.java +++ b/core/src/main/java/org/opensearch/sql/executor/streaming/Batch.java @@ -8,9 +8,7 @@ import lombok.Data; import org.opensearch.sql.storage.split.Split; -/** - * A batch of streaming execution. - */ +/** A batch of streaming execution. */ @Data public class Batch { private final Split split; diff --git a/core/src/main/java/org/opensearch/sql/executor/streaming/MicroBatchStreamingExecution.java b/core/src/main/java/org/opensearch/sql/executor/streaming/MicroBatchStreamingExecution.java index c31ed18c57..4e05484f15 100644 --- a/core/src/main/java/org/opensearch/sql/executor/streaming/MicroBatchStreamingExecution.java +++ b/core/src/main/java/org/opensearch/sql/executor/streaming/MicroBatchStreamingExecution.java @@ -20,9 +20,7 @@ import org.opensearch.sql.planner.PlanContext; import org.opensearch.sql.planner.logical.LogicalPlan; -/** - * Micro batch streaming execution. - */ +/** Micro batch streaming execution. */ public class MicroBatchStreamingExecution { private static final Logger log = LogManager.getLogger(MicroBatchStreamingExecution.class); @@ -46,9 +44,7 @@ public class MicroBatchStreamingExecution { /** keep track the latest commit batchId. */ private final MetadataLog committedLog; - /** - * Constructor. - */ + /** Constructor. */ public MicroBatchStreamingExecution( StreamingSource source, LogicalPlan batchPlan, @@ -63,9 +59,7 @@ public MicroBatchStreamingExecution( this.committedLog = committedLog; } - /** - * Pull the {@link Batch} from {@link StreamingSource} and execute the {@link Batch}. - */ + /** Pull the {@link Batch} from {@link StreamingSource} and execute the {@link Batch}. */ public void execute() { Long latestBatchId = offsetLog.getLatest().map(Pair::getKey).orElse(INITIAL_LATEST_BATCH_ID); Long latestCommittedBatchId = diff --git a/core/src/main/java/org/opensearch/sql/executor/streaming/Offset.java b/core/src/main/java/org/opensearch/sql/executor/streaming/Offset.java index 00f040e437..27960da84d 100644 --- a/core/src/main/java/org/opensearch/sql/executor/streaming/Offset.java +++ b/core/src/main/java/org/opensearch/sql/executor/streaming/Offset.java @@ -7,9 +7,7 @@ import lombok.Data; -/** - * Offset. - */ +/** Offset. */ @Data public class Offset { diff --git a/core/src/main/java/org/opensearch/sql/executor/streaming/StreamingSource.java b/core/src/main/java/org/opensearch/sql/executor/streaming/StreamingSource.java index ebd3fa714b..2b45a45d9a 100644 --- a/core/src/main/java/org/opensearch/sql/executor/streaming/StreamingSource.java +++ b/core/src/main/java/org/opensearch/sql/executor/streaming/StreamingSource.java @@ -7,9 +7,7 @@ import java.util.Optional; -/** - * Streaming source. - */ +/** Streaming source. */ public interface StreamingSource { /** * Get current {@link Offset} of stream data. diff --git a/core/src/main/java/org/opensearch/sql/expression/DSL.java b/core/src/main/java/org/opensearch/sql/expression/DSL.java index 3f1897e483..4341668b69 100644 --- a/core/src/main/java/org/opensearch/sql/expression/DSL.java +++ b/core/src/main/java/org/opensearch/sql/expression/DSL.java @@ -3,7 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ - package org.opensearch.sql.expression; import java.util.Arrays; @@ -29,8 +28,7 @@ public class DSL { - private DSL() { - } + private DSL() {} public static LiteralExpression literal(Byte value) { return new LiteralExpression(ExprValueUtils.byteValue(value)); @@ -68,9 +66,7 @@ public static LiteralExpression literal(ExprValue value) { return new LiteralExpression(value); } - /** - * Wrap a number to {@link LiteralExpression}. - */ + /** Wrap a number to {@link LiteralExpression}. */ public static LiteralExpression literal(Number value) { if (value instanceof Integer) { return new LiteralExpression(ExprValueUtils.integerValue(value.intValue())); @@ -88,21 +84,21 @@ public static ReferenceExpression ref(String ref, ExprType type) { } /** - * Wrap a named expression if not yet. The intent is that different languages may use - * Alias or not when building AST. This caused either named or unnamed expression - * is resolved by analyzer. To make unnamed expression acceptable for logical project, - * it is required to wrap it by named expression here before passing to logical project. + * Wrap a named expression if not yet. The intent is that different languages may use Alias or not + * when building AST. This caused either named or unnamed expression is resolved by analyzer. To + * make unnamed expression acceptable for logical project, it is required to wrap it by named + * expression here before passing to logical project. * - * @param expression expression - * @return expression if named already or expression wrapped by named expression. + * @param expression expression + * @return expression if named already or expression wrapped by named expression. */ public static NamedExpression named(Expression expression) { if (expression instanceof NamedExpression) { return (NamedExpression) expression; } if (expression instanceof ParseExpression) { - return named(((ParseExpression) expression).getIdentifier().valueOf().stringValue(), - expression); + return named( + ((ParseExpression) expression).getIdentifier().valueOf().stringValue(), expression); } return named(expression.toString(), expression); } @@ -127,18 +123,18 @@ public static NamedArgumentExpression namedArgument(String name, String value) { return namedArgument(name, literal(value)); } - public static GrokExpression grok(Expression sourceField, Expression pattern, - Expression identifier) { + public static GrokExpression grok( + Expression sourceField, Expression pattern, Expression identifier) { return new GrokExpression(sourceField, pattern, identifier); } - public static RegexExpression regex(Expression sourceField, Expression pattern, - Expression identifier) { + public static RegexExpression regex( + Expression sourceField, Expression pattern, Expression identifier) { return new RegexExpression(sourceField, pattern, identifier); } - public static PatternsExpression patterns(Expression sourceField, Expression pattern, - Expression identifier) { + public static PatternsExpression patterns( + Expression sourceField, Expression pattern, Expression identifier) { return new PatternsExpression(sourceField, pattern, identifier); } @@ -268,7 +264,6 @@ public static FunctionExpression signum(Expression... expressions) { public static FunctionExpression sinh(Expression... expressions) { return compile(FunctionProperties.None, BuiltinFunctionName.SINH, expressions); - } public static FunctionExpression sqrt(Expression... expressions) { @@ -364,8 +359,7 @@ public static FunctionExpression dayname(Expression... expressions) { } public static FunctionExpression dayofmonth( - FunctionProperties functionProperties, - Expression... expressions) { + FunctionProperties functionProperties, Expression... expressions) { return compile(functionProperties, BuiltinFunctionName.DAYOFMONTH, expressions); } @@ -379,8 +373,7 @@ public static FunctionExpression dayofyear(Expression... expressions) { } public static FunctionExpression day_of_month( - FunctionProperties functionProperties, - Expression... expressions) { + FunctionProperties functionProperties, Expression... expressions) { return compile(functionProperties, BuiltinFunctionName.DAY_OF_MONTH, expressions); } @@ -394,8 +387,8 @@ public static FunctionExpression day_of_week( return compile(functionProperties, BuiltinFunctionName.DAY_OF_WEEK, expressions); } - public static FunctionExpression extract(FunctionProperties functionProperties, - Expression... expressions) { + public static FunctionExpression extract( + FunctionProperties functionProperties, Expression... expressions) { return compile(functionProperties, BuiltinFunctionName.EXTRACT, expressions); } @@ -419,8 +412,8 @@ public static FunctionExpression hour_of_day(Expression... expressions) { return compile(FunctionProperties.None, BuiltinFunctionName.HOUR_OF_DAY, expressions); } - public static FunctionExpression last_day(FunctionProperties functionProperties, - Expression... expressions) { + public static FunctionExpression last_day( + FunctionProperties functionProperties, Expression... expressions) { return compile(functionProperties, BuiltinFunctionName.LAST_DAY, expressions); } @@ -477,14 +470,13 @@ public static FunctionExpression timestamp(Expression... expressions) { return timestamp(FunctionProperties.None, expressions); } - public static FunctionExpression timestamp(FunctionProperties functionProperties, - Expression... expressions) { + public static FunctionExpression timestamp( + FunctionProperties functionProperties, Expression... expressions) { return compile(functionProperties, BuiltinFunctionName.TIMESTAMP, expressions); } public static FunctionExpression date_format( - FunctionProperties functionProperties, - Expression... expressions) { + FunctionProperties functionProperties, Expression... expressions) { return compile(functionProperties, BuiltinFunctionName.DATE_FORMAT, expressions); } @@ -492,8 +484,8 @@ public static FunctionExpression to_days(Expression... expressions) { return compile(FunctionProperties.None, BuiltinFunctionName.TO_DAYS, expressions); } - public static FunctionExpression to_seconds(FunctionProperties functionProperties, - Expression... expressions) { + public static FunctionExpression to_seconds( + FunctionProperties functionProperties, Expression... expressions) { return compile(functionProperties, BuiltinFunctionName.TO_SECONDS, expressions); } @@ -506,8 +498,8 @@ public static FunctionExpression week( return compile(functionProperties, BuiltinFunctionName.WEEK, expressions); } - public static FunctionExpression weekday(FunctionProperties functionProperties, - Expression... expressions) { + public static FunctionExpression weekday( + FunctionProperties functionProperties, Expression... expressions) { return compile(functionProperties, BuiltinFunctionName.WEEKDAY, expressions); } @@ -530,13 +522,13 @@ public static FunctionExpression yearweek( return compile(functionProperties, BuiltinFunctionName.YEARWEEK, expressions); } - public static FunctionExpression str_to_date(FunctionProperties functionProperties, - Expression... expressions) { + public static FunctionExpression str_to_date( + FunctionProperties functionProperties, Expression... expressions) { return compile(functionProperties, BuiltinFunctionName.STR_TO_DATE, expressions); } - + public static FunctionExpression sec_to_time(Expression... expressions) { - return compile(FunctionProperties.None, BuiltinFunctionName.SEC_TO_TIME, expressions); + return compile(FunctionProperties.None, BuiltinFunctionName.SEC_TO_TIME, expressions); } public static FunctionExpression substr(Expression... expressions) { @@ -771,8 +763,7 @@ public static FunctionExpression iffunction(Expression... expressions) { return compile(FunctionProperties.None, BuiltinFunctionName.IF, expressions); } - public static Expression cases(Expression defaultResult, - WhenClause... whenClauses) { + public static Expression cases(Expression defaultResult, WhenClause... whenClauses) { return new CaseClause(Arrays.asList(whenClauses), defaultResult); } @@ -884,53 +875,52 @@ public static FunctionExpression score_query(Expression... args) { return compile(FunctionProperties.None, BuiltinFunctionName.SCORE_QUERY, args); } - public static FunctionExpression now(FunctionProperties functionProperties, - Expression... args) { + public static FunctionExpression now(FunctionProperties functionProperties, Expression... args) { return compile(functionProperties, BuiltinFunctionName.NOW, args); } - public static FunctionExpression current_timestamp(FunctionProperties functionProperties, - Expression... args) { + public static FunctionExpression current_timestamp( + FunctionProperties functionProperties, Expression... args) { return compile(functionProperties, BuiltinFunctionName.CURRENT_TIMESTAMP, args); } - public static FunctionExpression localtimestamp(FunctionProperties functionProperties, - Expression... args) { + public static FunctionExpression localtimestamp( + FunctionProperties functionProperties, Expression... args) { return compile(functionProperties, BuiltinFunctionName.LOCALTIMESTAMP, args); } - public static FunctionExpression localtime(FunctionProperties functionProperties, - Expression... args) { + public static FunctionExpression localtime( + FunctionProperties functionProperties, Expression... args) { return compile(functionProperties, BuiltinFunctionName.LOCALTIME, args); } - public static FunctionExpression sysdate(FunctionProperties functionProperties, - Expression... args) { + public static FunctionExpression sysdate( + FunctionProperties functionProperties, Expression... args) { return compile(functionProperties, BuiltinFunctionName.SYSDATE, args); } - public static FunctionExpression curtime(FunctionProperties functionProperties, - Expression... args) { + public static FunctionExpression curtime( + FunctionProperties functionProperties, Expression... args) { return compile(functionProperties, BuiltinFunctionName.CURTIME, args); } - public static FunctionExpression current_time(FunctionProperties functionProperties, - Expression... args) { + public static FunctionExpression current_time( + FunctionProperties functionProperties, Expression... args) { return compile(functionProperties, BuiltinFunctionName.CURRENT_TIME, args); } - public static FunctionExpression curdate(FunctionProperties functionProperties, - Expression... args) { + public static FunctionExpression curdate( + FunctionProperties functionProperties, Expression... args) { return compile(functionProperties, BuiltinFunctionName.CURDATE, args); } - public static FunctionExpression current_date(FunctionProperties functionProperties, - Expression... args) { + public static FunctionExpression current_date( + FunctionProperties functionProperties, Expression... args) { return compile(functionProperties, BuiltinFunctionName.CURRENT_DATE, args); } - public static FunctionExpression time_format(FunctionProperties functionProperties, - Expression... expressions) { + public static FunctionExpression time_format( + FunctionProperties functionProperties, Expression... expressions) { return compile(functionProperties, BuiltinFunctionName.TIME_FORMAT, expressions); } @@ -938,38 +928,36 @@ public static FunctionExpression timestampadd(Expression... expressions) { return timestampadd(FunctionProperties.None, expressions); } - public static FunctionExpression timestampadd(FunctionProperties functionProperties, - Expression... expressions) { + public static FunctionExpression timestampadd( + FunctionProperties functionProperties, Expression... expressions) { return compile(functionProperties, BuiltinFunctionName.TIMESTAMPADD, expressions); } - public static FunctionExpression timestampdiff(FunctionProperties functionProperties, - Expression... expressions) { + public static FunctionExpression timestampdiff( + FunctionProperties functionProperties, Expression... expressions) { return compile(functionProperties, BuiltinFunctionName.TIMESTAMPDIFF, expressions); } - - public static FunctionExpression utc_date(FunctionProperties functionProperties, - Expression... args) { + public static FunctionExpression utc_date( + FunctionProperties functionProperties, Expression... args) { return compile(functionProperties, BuiltinFunctionName.UTC_DATE, args); } - public static FunctionExpression utc_time(FunctionProperties functionProperties, - Expression... args) { + public static FunctionExpression utc_time( + FunctionProperties functionProperties, Expression... args) { return compile(functionProperties, BuiltinFunctionName.UTC_TIME, args); } - public static FunctionExpression utc_timestamp(FunctionProperties functionProperties, - Expression... args) { + public static FunctionExpression utc_timestamp( + FunctionProperties functionProperties, Expression... args) { return compile(functionProperties, BuiltinFunctionName.UTC_TIMESTAMP, args); - } @SuppressWarnings("unchecked") - private static - T compile(FunctionProperties functionProperties, - BuiltinFunctionName bfn, Expression... args) { - return (T) BuiltinFunctionRepository.getInstance().compile(functionProperties, - bfn.getName(), Arrays.asList(args)); + private static T compile( + FunctionProperties functionProperties, BuiltinFunctionName bfn, Expression... args) { + return (T) + BuiltinFunctionRepository.getInstance() + .compile(functionProperties, bfn.getName(), Arrays.asList(args)); } } diff --git a/core/src/main/java/org/opensearch/sql/expression/Expression.java b/core/src/main/java/org/opensearch/sql/expression/Expression.java index 25a8173efa..e4a5f908e5 100644 --- a/core/src/main/java/org/opensearch/sql/expression/Expression.java +++ b/core/src/main/java/org/opensearch/sql/expression/Expression.java @@ -3,7 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ - package org.opensearch.sql.expression; import java.io.Serializable; @@ -11,36 +10,28 @@ import org.opensearch.sql.data.type.ExprType; import org.opensearch.sql.expression.env.Environment; -/** - * The definition of the resolved expression. - */ +/** The definition of the resolved expression. */ public interface Expression extends Serializable { - /** - * Evaluate the value of expression that does not depend on value environment. - */ + /** Evaluate the value of expression that does not depend on value environment. */ default ExprValue valueOf() { return valueOf(null); } - /** - * Evaluate the value of expression in the value environment. - */ + /** Evaluate the value of expression in the value environment. */ ExprValue valueOf(Environment valueEnv); - /** - * The type of the expression. - */ + /** The type of the expression. */ ExprType type(); /** * Accept a visitor to visit current expression node. - * @param visitor visitor - * @param context context - * @param result type - * @param context type - * @return result accumulated by visitor when visiting + * + * @param visitor visitor + * @param context context + * @param result type + * @param context type + * @return result accumulated by visitor when visiting */ T accept(ExpressionNodeVisitor visitor, C context); - } diff --git a/core/src/main/java/org/opensearch/sql/expression/ExpressionNodeVisitor.java b/core/src/main/java/org/opensearch/sql/expression/ExpressionNodeVisitor.java index e3d4e38674..1f11f0805b 100644 --- a/core/src/main/java/org/opensearch/sql/expression/ExpressionNodeVisitor.java +++ b/core/src/main/java/org/opensearch/sql/expression/ExpressionNodeVisitor.java @@ -3,7 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ - package org.opensearch.sql.expression; import org.opensearch.sql.expression.aggregation.Aggregator; @@ -15,8 +14,9 @@ /** * Abstract visitor for expression tree nodes. - * @param type of return value to accumulate when visiting. - * @param type of context. + * + * @param type of return value to accumulate when visiting. + * @param type of context. */ public abstract class ExpressionNodeVisitor { @@ -26,9 +26,10 @@ public T visitNode(Expression node, C context) { /** * Visit children nodes in function arguments. - * @param node function node - * @param context context - * @return result + * + * @param node function node + * @param context context + * @return result */ public T visitChildren(FunctionImplementation node, C context) { T result = defaultResult(); @@ -81,10 +82,9 @@ public T visitNamedAggregator(NamedAggregator node, C context) { } /** - * Call visitFunction() by default rather than visitChildren(). - * This makes CASE/WHEN able to be handled: - * 1) by visitFunction() if not overwritten: ex. FilterQueryBuilder - * 2) by visitCase/When() otherwise if any special logic: ex. ExprReferenceOptimizer + * Call visitFunction() by default rather than visitChildren(). This makes CASE/WHEN able to be + * handled: 1) by visitFunction() if not overwritten: ex. FilterQueryBuilder 2) by + * visitCase/When() otherwise if any special logic: ex. ExprReferenceOptimizer */ public T visitCase(CaseClause node, C context) { return visitFunction(node, context); diff --git a/core/src/main/java/org/opensearch/sql/expression/FunctionExpression.java b/core/src/main/java/org/opensearch/sql/expression/FunctionExpression.java index 2a695f26e6..b67eb38c00 100644 --- a/core/src/main/java/org/opensearch/sql/expression/FunctionExpression.java +++ b/core/src/main/java/org/opensearch/sql/expression/FunctionExpression.java @@ -3,7 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ - package org.opensearch.sql.expression; import java.util.List; @@ -14,22 +13,17 @@ import org.opensearch.sql.expression.function.FunctionImplementation; import org.opensearch.sql.expression.function.FunctionName; -/** - * Function Expression. - */ +/** Function Expression. */ @EqualsAndHashCode @RequiredArgsConstructor @ToString public abstract class FunctionExpression implements Expression, FunctionImplementation { - @Getter - private final FunctionName functionName; + @Getter private final FunctionName functionName; - @Getter - private final List arguments; + @Getter private final List arguments; @Override public T accept(ExpressionNodeVisitor visitor, C context) { return visitor.visitFunction(this, context); } - } diff --git a/core/src/main/java/org/opensearch/sql/expression/HighlightExpression.java b/core/src/main/java/org/opensearch/sql/expression/HighlightExpression.java index 804c38a6f7..79cc07f048 100644 --- a/core/src/main/java/org/opensearch/sql/expression/HighlightExpression.java +++ b/core/src/main/java/org/opensearch/sql/expression/HighlightExpression.java @@ -20,9 +20,7 @@ import org.opensearch.sql.expression.env.Environment; import org.opensearch.sql.expression.function.BuiltinFunctionName; -/** - * Highlight Expression. - */ +/** Highlight Expression. */ @Getter public class HighlightExpression extends FunctionExpression { private final Expression highlightField; @@ -30,17 +28,19 @@ public class HighlightExpression extends FunctionExpression { /** * HighlightExpression Constructor. + * * @param highlightField : Highlight field for expression. */ public HighlightExpression(Expression highlightField) { super(BuiltinFunctionName.HIGHLIGHT.getName(), List.of(highlightField)); this.highlightField = highlightField; - this.type = this.highlightField.toString().contains("*") - ? ExprCoreType.STRUCT : ExprCoreType.ARRAY; + this.type = + this.highlightField.toString().contains("*") ? ExprCoreType.STRUCT : ExprCoreType.ARRAY; } /** * Return collection value matching highlight field. + * * @param valueEnv : Dataset to parse value from. * @return : collection value of highlight fields. */ @@ -57,15 +57,15 @@ public ExprValue valueOf(Environment valueEnv) { // used in conjunction with other highlight calls, we need to ensure // only wildcard regex matching is mapped to wildcard call. if (this.type == ExprCoreType.STRUCT && value.type() == ExprCoreType.STRUCT) { - value = new ExprTupleValue( - new LinkedHashMap(value.tupleValue() - .entrySet() - .stream() - .filter(s -> matchesHighlightRegex(s.getKey(), - StringUtils.unquoteText(highlightField.toString()))) - .collect(Collectors.toMap( - e -> e.getKey(), - e -> e.getValue())))); + value = + new ExprTupleValue( + new LinkedHashMap( + value.tupleValue().entrySet().stream() + .filter( + s -> + matchesHighlightRegex( + s.getKey(), StringUtils.unquoteText(highlightField.toString()))) + .collect(Collectors.toMap(e -> e.getKey(), e -> e.getValue())))); if (value.tupleValue().isEmpty()) { value = ExprValueUtils.missingValue(); } @@ -76,6 +76,7 @@ public ExprValue valueOf(Environment valueEnv) { /** * Get type for HighlightExpression. + * * @return : Expression type. */ @Override @@ -90,6 +91,7 @@ public T accept(ExpressionNodeVisitor visitor, C context) { /** * Check if field matches the wildcard pattern used in highlight query. + * * @param field Highlight selected field for query * @param pattern Wildcard regex to match field against * @return True if field matches wildcard pattern diff --git a/core/src/main/java/org/opensearch/sql/expression/LiteralExpression.java b/core/src/main/java/org/opensearch/sql/expression/LiteralExpression.java index adb8e197d1..eba03e8430 100644 --- a/core/src/main/java/org/opensearch/sql/expression/LiteralExpression.java +++ b/core/src/main/java/org/opensearch/sql/expression/LiteralExpression.java @@ -3,7 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ - package org.opensearch.sql.expression; import lombok.EqualsAndHashCode; @@ -12,9 +11,7 @@ import org.opensearch.sql.data.type.ExprType; import org.opensearch.sql.expression.env.Environment; -/** - * Literal Expression. - */ +/** Literal Expression. */ @EqualsAndHashCode @RequiredArgsConstructor public class LiteralExpression implements Expression { diff --git a/core/src/main/java/org/opensearch/sql/expression/NamedArgumentExpression.java b/core/src/main/java/org/opensearch/sql/expression/NamedArgumentExpression.java index 0f4601f1bf..c3ce60bd4a 100644 --- a/core/src/main/java/org/opensearch/sql/expression/NamedArgumentExpression.java +++ b/core/src/main/java/org/opensearch/sql/expression/NamedArgumentExpression.java @@ -13,9 +13,7 @@ import org.opensearch.sql.data.type.ExprType; import org.opensearch.sql.expression.env.Environment; -/** - * Named argument expression that represents function argument with name. - */ +/** Named argument expression that represents function argument with name. */ @RequiredArgsConstructor @Getter @EqualsAndHashCode diff --git a/core/src/main/java/org/opensearch/sql/expression/NamedExpression.java b/core/src/main/java/org/opensearch/sql/expression/NamedExpression.java index 26996eb93d..febd468e72 100644 --- a/core/src/main/java/org/opensearch/sql/expression/NamedExpression.java +++ b/core/src/main/java/org/opensearch/sql/expression/NamedExpression.java @@ -3,7 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ - package org.opensearch.sql.expression; import com.google.common.base.Strings; @@ -16,9 +15,8 @@ import org.opensearch.sql.expression.env.Environment; /** - * Named expression that represents expression with name. - * Please see more details in associated unresolved expression operator - * {@link org.opensearch.sql.ast.expression.Alias}. + * Named expression that represents expression with name. Please see more details in associated + * unresolved expression operator {@link org.opensearch.sql.ast.expression.Alias}. */ @AllArgsConstructor @EqualsAndHashCode @@ -26,19 +24,13 @@ @RequiredArgsConstructor public class NamedExpression implements Expression { - /** - * Expression name. - */ + /** Expression name. */ private final String name; - /** - * Expression that being named. - */ + /** Expression that being named. */ private final Expression delegated; - /** - * Optional alias. - */ + /** Optional alias. */ private String alias; @Override @@ -53,7 +45,8 @@ public ExprType type() { /** * Get expression name using name or its alias (if it's present). - * @return expression name + * + * @return expression name */ public String getNameOrAlias() { return Strings.isNullOrEmpty(alias) ? name : alias; @@ -68,5 +61,4 @@ public T accept(ExpressionNodeVisitor visitor, C context) { public String toString() { return getNameOrAlias(); } - } diff --git a/core/src/main/java/org/opensearch/sql/expression/ReferenceExpression.java b/core/src/main/java/org/opensearch/sql/expression/ReferenceExpression.java index 3c5b2af23c..67a916a786 100644 --- a/core/src/main/java/org/opensearch/sql/expression/ReferenceExpression.java +++ b/core/src/main/java/org/opensearch/sql/expression/ReferenceExpression.java @@ -3,7 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ - package org.opensearch.sql.expression; import static org.opensearch.sql.utils.ExpressionUtils.PATH_SEP; @@ -22,16 +21,15 @@ @EqualsAndHashCode @RequiredArgsConstructor public class ReferenceExpression implements Expression { - @Getter - private final String attr; + @Getter private final String attr; - @Getter - private final List paths; + @Getter private final List paths; private final ExprType type; /** * Constructor of ReferenceExpression. + * * @param ref the field name. e.g. addr.state/addr. * @param type type. */ @@ -63,34 +61,17 @@ public String toString() { } /** - * Resolve the ExprValue from {@link ExprTupleValue} using paths. - * Considering the following sample data. - * { - * "name": "bob smith" - * "project.year": 1990, - * "project": { - * "year": "2020" - * } - * "address": { - * "state": "WA", - * "city": "seattle", - * "project.year": 1990 - * } - * "address.local": { - * "state": "WA", - * } - * } - * The paths could be - * 1. top level, e.g. "name", which will be resolved as "bob smith" - * 2. multiple paths, e.g. "name.address.state", which will be resolved as "WA" - * 3. special case, the "." is the path separator, but it is possible that the path include - * ".", for handling this use case, we define the resolve rule as bellow, e.g. "project.year" is - * resolved as 1990 instead of 2020. Note. This logic only applied top level none object field. - * e.g. "address.local.state" been resolved to Missing. but "address.project.year" could been - * resolved as 1990. + * Resolve the ExprValue from {@link ExprTupleValue} using paths. Considering the following sample + * data. { "name": "bob smith" "project.year": 1990, "project": { "year": "2020" } "address": { + * "state": "WA", "city": "seattle", "project.year": 1990 } "address.local": { "state": "WA", } } + * The paths could be 1. top level, e.g. "name", which will be resolved as "bob smith" 2. multiple + * paths, e.g. "name.address.state", which will be resolved as "WA" 3. special case, the "." is + * the path separator, but it is possible that the path include ".", for handling this use case, + * we define the resolve rule as bellow, e.g. "project.year" is resolved as 1990 instead of 2020. + * Note. This logic only applied top level none object field. e.g. "address.local.state" been + * resolved to Missing. but "address.project.year" could been resolved as 1990. * - *

Resolve Rule - * 1. Resolve the full name by combine the paths("x"."y"."z") as whole ("x.y.z"). + *

Resolve Rule 1. Resolve the full name by combine the paths("x"."y"."z") as whole ("x.y.z"). * 2. Resolve the path recursively through ExprValue. * * @param value {@link ExprTupleValue}. diff --git a/core/src/main/java/org/opensearch/sql/expression/aggregation/AggregationState.java b/core/src/main/java/org/opensearch/sql/expression/aggregation/AggregationState.java index 345c6c00dd..478e3caf54 100644 --- a/core/src/main/java/org/opensearch/sql/expression/aggregation/AggregationState.java +++ b/core/src/main/java/org/opensearch/sql/expression/aggregation/AggregationState.java @@ -3,18 +3,13 @@ * SPDX-License-Identifier: Apache-2.0 */ - package org.opensearch.sql.expression.aggregation; import org.opensearch.sql.data.model.ExprValue; import org.opensearch.sql.storage.bindingtuple.BindingTuple; -/** - * Maintain the state when {@link Aggregator} iterate on the {@link BindingTuple}. - */ +/** Maintain the state when {@link Aggregator} iterate on the {@link BindingTuple}. */ public interface AggregationState { - /** - * Get {@link ExprValue} result. - */ + /** Get {@link ExprValue} result. */ ExprValue result(); } diff --git a/core/src/main/java/org/opensearch/sql/expression/aggregation/Aggregator.java b/core/src/main/java/org/opensearch/sql/expression/aggregation/Aggregator.java index a122ea6540..a2a3ce76c3 100644 --- a/core/src/main/java/org/opensearch/sql/expression/aggregation/Aggregator.java +++ b/core/src/main/java/org/opensearch/sql/expression/aggregation/Aggregator.java @@ -3,7 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ - package org.opensearch.sql.expression.aggregation; import java.util.List; @@ -26,36 +25,34 @@ import org.opensearch.sql.storage.bindingtuple.BindingTuple; /** - * Aggregator which will iterate on the {@link BindingTuple}s to aggregate the result. - * The Aggregator is not well fit into Expression, because it has side effect. - * But we still want to make it implement {@link Expression} interface to make - * {@link ExpressionAnalyzer} easier. + * Aggregator which will iterate on the {@link BindingTuple}s to aggregate the result. The + * Aggregator is not well fit into Expression, because it has side effect. But we still want to make + * it implement {@link Expression} interface to make {@link ExpressionAnalyzer} easier. */ @EqualsAndHashCode @RequiredArgsConstructor public abstract class Aggregator implements FunctionImplementation, Expression { - @Getter - private final FunctionName functionName; - @Getter - private final List arguments; + @Getter private final FunctionName functionName; + @Getter private final List arguments; protected final ExprCoreType returnType; + @Setter @Getter @Accessors(fluent = true) protected Expression condition; + @Setter @Getter @Accessors(fluent = true) protected Boolean distinct = false; - /** - * Create an {@link AggregationState} which will be used for aggregation. - */ + /** Create an {@link AggregationState} which will be used for aggregation. */ public abstract S create(); /** * Iterate on {@link ExprValue}. + * * @param value {@link ExprValue} * @param state {@link AggregationState} * @return {@link AggregationState} @@ -63,9 +60,9 @@ public abstract class Aggregator protected abstract S iterate(ExprValue value, S state); /** - * Let the aggregator iterate on the {@link BindingTuple} - * To filter out ExprValues that are missing, null or cannot satisfy {@link #condition} - * Before the specific aggregator iterating ExprValue in the tuple. + * Let the aggregator iterate on the {@link BindingTuple} To filter out ExprValues that are + * missing, null or cannot satisfy {@link #condition} Before the specific aggregator iterating + * ExprValue in the tuple. * * @param tuple {@link BindingTuple} * @param state {@link AggregationState} @@ -95,14 +92,11 @@ public T accept(ExpressionNodeVisitor visitor, C context) { return visitor.visitAggregator(this, context); } - /** - * Util method to get value of condition in aggregation filter. - */ + /** Util method to get value of condition in aggregation filter. */ public boolean conditionValue(BindingTuple tuple) { if (condition == null) { return true; } return ExprValueUtils.getBooleanValue(condition.valueOf(tuple)); } - } diff --git a/core/src/main/java/org/opensearch/sql/expression/aggregation/AggregatorFunction.java b/core/src/main/java/org/opensearch/sql/expression/aggregation/AggregatorFunction.java index a24eeca1c1..944bb7b50f 100644 --- a/core/src/main/java/org/opensearch/sql/expression/aggregation/AggregatorFunction.java +++ b/core/src/main/java/org/opensearch/sql/expression/aggregation/AggregatorFunction.java @@ -3,7 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ - package org.opensearch.sql.expression.aggregation; import static org.opensearch.sql.data.type.ExprCoreType.ARRAY; @@ -35,12 +34,9 @@ import org.opensearch.sql.expression.function.FunctionSignature; /** - * The definition of aggregator function - * avg, Accepts two numbers and produces a number. - * sum, Accepts two numbers and produces a number. - * max, Accepts two numbers and produces a number. - * min, Accepts two numbers and produces a number. - * count, Accepts two numbers and produces a number. + * The definition of aggregator function avg, Accepts two numbers and produces a number. sum, + * Accepts two numbers and produces a number. max, Accepts two numbers and produces a number. min, + * Accepts two numbers and produces a number. count, Accepts two numbers and produces a number. */ @UtilityClass public class AggregatorFunction { @@ -67,26 +63,37 @@ private static DefaultFunctionResolver avg() { return new DefaultFunctionResolver( functionName, new ImmutableMap.Builder() - .put(new FunctionSignature(functionName, Collections.singletonList(DOUBLE)), + .put( + new FunctionSignature(functionName, Collections.singletonList(DOUBLE)), (functionProperties, arguments) -> new AvgAggregator(arguments, DOUBLE)) - .put(new FunctionSignature(functionName, Collections.singletonList(DATE)), + .put( + new FunctionSignature(functionName, Collections.singletonList(DATE)), (functionProperties, arguments) -> new AvgAggregator(arguments, DATE)) - .put(new FunctionSignature(functionName, Collections.singletonList(DATETIME)), + .put( + new FunctionSignature(functionName, Collections.singletonList(DATETIME)), (functionProperties, arguments) -> new AvgAggregator(arguments, DATETIME)) - .put(new FunctionSignature(functionName, Collections.singletonList(TIME)), + .put( + new FunctionSignature(functionName, Collections.singletonList(TIME)), (functionProperties, arguments) -> new AvgAggregator(arguments, TIME)) - .put(new FunctionSignature(functionName, Collections.singletonList(TIMESTAMP)), + .put( + new FunctionSignature(functionName, Collections.singletonList(TIMESTAMP)), (functionProperties, arguments) -> new AvgAggregator(arguments, TIMESTAMP)) - .build() - ); + .build()); } private static DefaultFunctionResolver count() { FunctionName functionName = BuiltinFunctionName.COUNT.getName(); - DefaultFunctionResolver functionResolver = new DefaultFunctionResolver(functionName, - ExprCoreType.coreTypes().stream().collect(Collectors.toMap( - type -> new FunctionSignature(functionName, Collections.singletonList(type)), - type -> (functionProperties, arguments) -> new CountAggregator(arguments, INTEGER)))); + DefaultFunctionResolver functionResolver = + new DefaultFunctionResolver( + functionName, + ExprCoreType.coreTypes().stream() + .collect( + Collectors.toMap( + type -> + new FunctionSignature(functionName, Collections.singletonList(type)), + type -> + (functionProperties, arguments) -> + new CountAggregator(arguments, INTEGER)))); return functionResolver; } @@ -95,16 +102,19 @@ private static DefaultFunctionResolver sum() { return new DefaultFunctionResolver( functionName, new ImmutableMap.Builder() - .put(new FunctionSignature(functionName, Collections.singletonList(INTEGER)), + .put( + new FunctionSignature(functionName, Collections.singletonList(INTEGER)), (functionProperties, arguments) -> new SumAggregator(arguments, INTEGER)) - .put(new FunctionSignature(functionName, Collections.singletonList(LONG)), + .put( + new FunctionSignature(functionName, Collections.singletonList(LONG)), (functionProperties, arguments) -> new SumAggregator(arguments, LONG)) - .put(new FunctionSignature(functionName, Collections.singletonList(FLOAT)), + .put( + new FunctionSignature(functionName, Collections.singletonList(FLOAT)), (functionProperties, arguments) -> new SumAggregator(arguments, FLOAT)) - .put(new FunctionSignature(functionName, Collections.singletonList(DOUBLE)), + .put( + new FunctionSignature(functionName, Collections.singletonList(DOUBLE)), (functionProperties, arguments) -> new SumAggregator(arguments, DOUBLE)) - .build() - ); + .build()); } private static DefaultFunctionResolver min() { @@ -112,23 +122,32 @@ private static DefaultFunctionResolver min() { return new DefaultFunctionResolver( functionName, new ImmutableMap.Builder() - .put(new FunctionSignature(functionName, Collections.singletonList(INTEGER)), + .put( + new FunctionSignature(functionName, Collections.singletonList(INTEGER)), (functionProperties, arguments) -> new MinAggregator(arguments, INTEGER)) - .put(new FunctionSignature(functionName, Collections.singletonList(LONG)), + .put( + new FunctionSignature(functionName, Collections.singletonList(LONG)), (functionProperties, arguments) -> new MinAggregator(arguments, LONG)) - .put(new FunctionSignature(functionName, Collections.singletonList(FLOAT)), + .put( + new FunctionSignature(functionName, Collections.singletonList(FLOAT)), (functionProperties, arguments) -> new MinAggregator(arguments, FLOAT)) - .put(new FunctionSignature(functionName, Collections.singletonList(DOUBLE)), + .put( + new FunctionSignature(functionName, Collections.singletonList(DOUBLE)), (functionProperties, arguments) -> new MinAggregator(arguments, DOUBLE)) - .put(new FunctionSignature(functionName, Collections.singletonList(STRING)), + .put( + new FunctionSignature(functionName, Collections.singletonList(STRING)), (functionProperties, arguments) -> new MinAggregator(arguments, STRING)) - .put(new FunctionSignature(functionName, Collections.singletonList(DATE)), + .put( + new FunctionSignature(functionName, Collections.singletonList(DATE)), (functionProperties, arguments) -> new MinAggregator(arguments, DATE)) - .put(new FunctionSignature(functionName, Collections.singletonList(DATETIME)), + .put( + new FunctionSignature(functionName, Collections.singletonList(DATETIME)), (functionProperties, arguments) -> new MinAggregator(arguments, DATETIME)) - .put(new FunctionSignature(functionName, Collections.singletonList(TIME)), + .put( + new FunctionSignature(functionName, Collections.singletonList(TIME)), (functionProperties, arguments) -> new MinAggregator(arguments, TIME)) - .put(new FunctionSignature(functionName, Collections.singletonList(TIMESTAMP)), + .put( + new FunctionSignature(functionName, Collections.singletonList(TIMESTAMP)), (functionProperties, arguments) -> new MinAggregator(arguments, TIMESTAMP)) .build()); } @@ -138,26 +157,34 @@ private static DefaultFunctionResolver max() { return new DefaultFunctionResolver( functionName, new ImmutableMap.Builder() - .put(new FunctionSignature(functionName, Collections.singletonList(INTEGER)), + .put( + new FunctionSignature(functionName, Collections.singletonList(INTEGER)), (functionProperties, arguments) -> new MaxAggregator(arguments, INTEGER)) - .put(new FunctionSignature(functionName, Collections.singletonList(LONG)), + .put( + new FunctionSignature(functionName, Collections.singletonList(LONG)), (functionProperties, arguments) -> new MaxAggregator(arguments, LONG)) - .put(new FunctionSignature(functionName, Collections.singletonList(FLOAT)), + .put( + new FunctionSignature(functionName, Collections.singletonList(FLOAT)), (functionProperties, arguments) -> new MaxAggregator(arguments, FLOAT)) - .put(new FunctionSignature(functionName, Collections.singletonList(DOUBLE)), + .put( + new FunctionSignature(functionName, Collections.singletonList(DOUBLE)), (functionProperties, arguments) -> new MaxAggregator(arguments, DOUBLE)) - .put(new FunctionSignature(functionName, Collections.singletonList(STRING)), + .put( + new FunctionSignature(functionName, Collections.singletonList(STRING)), (functionProperties, arguments) -> new MaxAggregator(arguments, STRING)) - .put(new FunctionSignature(functionName, Collections.singletonList(DATE)), + .put( + new FunctionSignature(functionName, Collections.singletonList(DATE)), (functionProperties, arguments) -> new MaxAggregator(arguments, DATE)) - .put(new FunctionSignature(functionName, Collections.singletonList(DATETIME)), + .put( + new FunctionSignature(functionName, Collections.singletonList(DATETIME)), (functionProperties, arguments) -> new MaxAggregator(arguments, DATETIME)) - .put(new FunctionSignature(functionName, Collections.singletonList(TIME)), + .put( + new FunctionSignature(functionName, Collections.singletonList(TIME)), (functionProperties, arguments) -> new MaxAggregator(arguments, TIME)) - .put(new FunctionSignature(functionName, Collections.singletonList(TIMESTAMP)), + .put( + new FunctionSignature(functionName, Collections.singletonList(TIMESTAMP)), (functionProperties, arguments) -> new MaxAggregator(arguments, TIMESTAMP)) - .build() - ); + .build()); } private static DefaultFunctionResolver varSamp() { @@ -165,10 +192,10 @@ private static DefaultFunctionResolver varSamp() { return new DefaultFunctionResolver( functionName, new ImmutableMap.Builder() - .put(new FunctionSignature(functionName, Collections.singletonList(DOUBLE)), + .put( + new FunctionSignature(functionName, Collections.singletonList(DOUBLE)), (functionProperties, arguments) -> varianceSample(arguments, DOUBLE)) - .build() - ); + .build()); } private static DefaultFunctionResolver varPop() { @@ -176,10 +203,10 @@ private static DefaultFunctionResolver varPop() { return new DefaultFunctionResolver( functionName, new ImmutableMap.Builder() - .put(new FunctionSignature(functionName, Collections.singletonList(DOUBLE)), + .put( + new FunctionSignature(functionName, Collections.singletonList(DOUBLE)), (functionProperties, arguments) -> variancePopulation(arguments, DOUBLE)) - .build() - ); + .build()); } private static DefaultFunctionResolver stddevSamp() { @@ -187,10 +214,10 @@ private static DefaultFunctionResolver stddevSamp() { return new DefaultFunctionResolver( functionName, new ImmutableMap.Builder() - .put(new FunctionSignature(functionName, Collections.singletonList(DOUBLE)), + .put( + new FunctionSignature(functionName, Collections.singletonList(DOUBLE)), (functionProperties, arguments) -> stddevSample(arguments, DOUBLE)) - .build() - ); + .build()); } private static DefaultFunctionResolver stddevPop() { @@ -198,20 +225,22 @@ private static DefaultFunctionResolver stddevPop() { return new DefaultFunctionResolver( functionName, new ImmutableMap.Builder() - .put(new FunctionSignature(functionName, Collections.singletonList(DOUBLE)), + .put( + new FunctionSignature(functionName, Collections.singletonList(DOUBLE)), (functionProperties, arguments) -> stddevPopulation(arguments, DOUBLE)) - .build() - ); + .build()); } private static DefaultFunctionResolver take() { FunctionName functionName = BuiltinFunctionName.TAKE.getName(); - DefaultFunctionResolver functionResolver = new DefaultFunctionResolver(functionName, - new ImmutableMap.Builder() - .put(new FunctionSignature(functionName, ImmutableList.of(STRING, INTEGER)), - (functionProperties, arguments) -> new TakeAggregator(arguments, ARRAY)) - .build()); + DefaultFunctionResolver functionResolver = + new DefaultFunctionResolver( + functionName, + new ImmutableMap.Builder() + .put( + new FunctionSignature(functionName, ImmutableList.of(STRING, INTEGER)), + (functionProperties, arguments) -> new TakeAggregator(arguments, ARRAY)) + .build()); return functionResolver; } - } diff --git a/core/src/main/java/org/opensearch/sql/expression/aggregation/AvgAggregator.java b/core/src/main/java/org/opensearch/sql/expression/aggregation/AvgAggregator.java index a899a6b45b..c528968018 100644 --- a/core/src/main/java/org/opensearch/sql/expression/aggregation/AvgAggregator.java +++ b/core/src/main/java/org/opensearch/sql/expression/aggregation/AvgAggregator.java @@ -3,7 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ - package org.opensearch.sql.expression.aggregation; import static java.time.temporal.ChronoUnit.MILLIS; @@ -27,14 +26,14 @@ import org.opensearch.sql.expression.function.BuiltinFunctionName; /** - * The average aggregator aggregate the value evaluated by the expression. - * If the expression evaluated result is NULL or MISSING, then the result is NULL. + * The average aggregator aggregate the value evaluated by the expression. If the expression + * evaluated result is NULL or MISSING, then the result is NULL. */ public class AvgAggregator extends Aggregator { /** - * To process by different ways different data types, we need to store the type. - * Input data has the same type as the result. + * To process by different ways different data types, we need to store the type. Input data has + * the same type as the result. */ private final ExprCoreType dataType; @@ -56,7 +55,7 @@ public AvgState create() { return new TimeAvgState(); case DOUBLE: return new DoubleAvgState(); - default: //unreachable code - we don't expose signatures for unsupported types + default: // unreachable code - we don't expose signatures for unsupported types throw new IllegalArgumentException( String.format("avg aggregation over %s type is not supported", dataType)); } @@ -72,9 +71,7 @@ public String toString() { return String.format(Locale.ROOT, "avg(%s)", format(getArguments())); } - /** - * Average State. - */ + /** Average State. */ protected abstract static class AvgState implements AggregationState { protected ExprValue count; protected ExprValue total; @@ -117,15 +114,16 @@ public ExprValue result() { } return new ExprDateValue( - new ExprTimestampValue(Instant.ofEpochMilli( - DSL.divide(DSL.literal(total), DSL.literal(count)).valueOf().longValue())) - .dateValue()); + new ExprTimestampValue( + Instant.ofEpochMilli( + DSL.divide(DSL.literal(total), DSL.literal(count)).valueOf().longValue())) + .dateValue()); } @Override protected AvgState iterate(ExprValue value) { - total = DSL.add(DSL.literal(total), DSL.literal(value.timestampValue().toEpochMilli())) - .valueOf(); + total = + DSL.add(DSL.literal(total), DSL.literal(value.timestampValue().toEpochMilli())).valueOf(); return super.iterate(value); } } @@ -138,15 +136,16 @@ public ExprValue result() { } return new ExprDatetimeValue( - new ExprTimestampValue(Instant.ofEpochMilli( - DSL.divide(DSL.literal(total), DSL.literal(count)).valueOf().longValue())) - .datetimeValue()); + new ExprTimestampValue( + Instant.ofEpochMilli( + DSL.divide(DSL.literal(total), DSL.literal(count)).valueOf().longValue())) + .datetimeValue()); } @Override protected AvgState iterate(ExprValue value) { - total = DSL.add(DSL.literal(total), DSL.literal(value.timestampValue().toEpochMilli())) - .valueOf(); + total = + DSL.add(DSL.literal(total), DSL.literal(value.timestampValue().toEpochMilli())).valueOf(); return super.iterate(value); } } @@ -158,14 +157,15 @@ public ExprValue result() { return ExprNullValue.of(); } - return new ExprTimestampValue(Instant.ofEpochMilli( - DSL.divide(DSL.literal(total), DSL.literal(count)).valueOf().longValue())); + return new ExprTimestampValue( + Instant.ofEpochMilli( + DSL.divide(DSL.literal(total), DSL.literal(count)).valueOf().longValue())); } @Override protected AvgState iterate(ExprValue value) { - total = DSL.add(DSL.literal(total), DSL.literal(value.timestampValue().toEpochMilli())) - .valueOf(); + total = + DSL.add(DSL.literal(total), DSL.literal(value.timestampValue().toEpochMilli())).valueOf(); return super.iterate(value); } } @@ -177,14 +177,16 @@ public ExprValue result() { return ExprNullValue.of(); } - return new ExprTimeValue(LocalTime.MIN.plus( - DSL.divide(DSL.literal(total), DSL.literal(count)).valueOf().longValue(), MILLIS)); + return new ExprTimeValue( + LocalTime.MIN.plus( + DSL.divide(DSL.literal(total), DSL.literal(count)).valueOf().longValue(), MILLIS)); } @Override protected AvgState iterate(ExprValue value) { - total = DSL.add(DSL.literal(total), - DSL.literal(MILLIS.between(LocalTime.MIN, value.timeValue()))).valueOf(); + total = + DSL.add(DSL.literal(total), DSL.literal(MILLIS.between(LocalTime.MIN, value.timeValue()))) + .valueOf(); return super.iterate(value); } } diff --git a/core/src/main/java/org/opensearch/sql/expression/aggregation/CountAggregator.java b/core/src/main/java/org/opensearch/sql/expression/aggregation/CountAggregator.java index 813842cadc..c4c02eb1d3 100644 --- a/core/src/main/java/org/opensearch/sql/expression/aggregation/CountAggregator.java +++ b/core/src/main/java/org/opensearch/sql/expression/aggregation/CountAggregator.java @@ -3,7 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ - package org.opensearch.sql.expression.aggregation; import static org.opensearch.sql.utils.ExpressionUtils.format; @@ -43,9 +42,7 @@ public String toString() { : String.format(Locale.ROOT, "count(%s)", format(getArguments())); } - /** - * Count State. - */ + /** Count State. */ protected static class CountState implements AggregationState { protected int count; diff --git a/core/src/main/java/org/opensearch/sql/expression/aggregation/MaxAggregator.java b/core/src/main/java/org/opensearch/sql/expression/aggregation/MaxAggregator.java index e9123c0ac2..863d4603a7 100644 --- a/core/src/main/java/org/opensearch/sql/expression/aggregation/MaxAggregator.java +++ b/core/src/main/java/org/opensearch/sql/expression/aggregation/MaxAggregator.java @@ -3,7 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ - package org.opensearch.sql.expression.aggregation; import static org.opensearch.sql.data.model.ExprValueUtils.LITERAL_NULL; @@ -45,9 +44,7 @@ protected static class MaxState implements AggregationState { } public void max(ExprValue value) { - maxResult = maxResult.isNull() ? value - : (maxResult.compareTo(value) > 0) - ? maxResult : value; + maxResult = maxResult.isNull() ? value : (maxResult.compareTo(value) > 0) ? maxResult : value; } @Override diff --git a/core/src/main/java/org/opensearch/sql/expression/aggregation/MinAggregator.java b/core/src/main/java/org/opensearch/sql/expression/aggregation/MinAggregator.java index 897fe857ff..c1b9ebcd4f 100644 --- a/core/src/main/java/org/opensearch/sql/expression/aggregation/MinAggregator.java +++ b/core/src/main/java/org/opensearch/sql/expression/aggregation/MinAggregator.java @@ -3,7 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ - package org.opensearch.sql.expression.aggregation; import static org.opensearch.sql.data.model.ExprValueUtils.LITERAL_NULL; @@ -16,8 +15,8 @@ import org.opensearch.sql.expression.function.BuiltinFunctionName; /** - * The minimum aggregator aggregate the value evaluated by the expression. - * If the expression evaluated result is NULL or MISSING, then the result is NULL. + * The minimum aggregator aggregate the value evaluated by the expression. If the expression + * evaluated result is NULL or MISSING, then the result is NULL. */ public class MinAggregator extends Aggregator { @@ -25,7 +24,6 @@ public MinAggregator(List arguments, ExprCoreType returnType) { super(BuiltinFunctionName.MIN.getName(), arguments, returnType); } - @Override public MinState create() { return new MinState(); @@ -50,9 +48,7 @@ protected static class MinState implements AggregationState { } public void min(ExprValue value) { - minResult = minResult.isNull() ? value - : (minResult.compareTo(value) < 0) - ? minResult : value; + minResult = minResult.isNull() ? value : (minResult.compareTo(value) < 0) ? minResult : value; } @Override diff --git a/core/src/main/java/org/opensearch/sql/expression/aggregation/NamedAggregator.java b/core/src/main/java/org/opensearch/sql/expression/aggregation/NamedAggregator.java index 510c5d1e45..1c10af5fc7 100644 --- a/core/src/main/java/org/opensearch/sql/expression/aggregation/NamedAggregator.java +++ b/core/src/main/java/org/opensearch/sql/expression/aggregation/NamedAggregator.java @@ -3,7 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ - package org.opensearch.sql.expression.aggregation; import lombok.EqualsAndHashCode; @@ -12,35 +11,26 @@ import org.opensearch.sql.expression.ExpressionNodeVisitor; /** - * NamedAggregator expression that represents expression with name. - * Please see more details in associated unresolved expression operator - * {@link org.opensearch.sql.ast.expression.Alias}. + * NamedAggregator expression that represents expression with name. Please see more details in + * associated unresolved expression operator {@link org.opensearch.sql.ast.expression.Alias}. */ @EqualsAndHashCode(callSuper = false) public class NamedAggregator extends Aggregator { - /** - * Aggregator name. - */ + /** Aggregator name. */ private final String name; - /** - * Aggregator that being named. - */ - @Getter - private final Aggregator delegated; + /** Aggregator that being named. */ + @Getter private final Aggregator delegated; /** - * NamedAggregator. - * The aggregator properties {@link #condition} and {@link #distinct} - * are inherited by named aggregator to avoid errors introduced by the property inconsistency. + * NamedAggregator. The aggregator properties {@link #condition} and {@link #distinct} are + * inherited by named aggregator to avoid errors introduced by the property inconsistency. * * @param name name * @param delegated delegated */ - public NamedAggregator( - String name, - Aggregator delegated) { + public NamedAggregator(String name, Aggregator delegated) { super(delegated.getFunctionName(), delegated.getArguments(), delegated.returnType); this.name = name; this.delegated = delegated; @@ -60,7 +50,8 @@ protected AggregationState iterate(ExprValue value, AggregationState state) { /** * Get expression name using name or its alias (if it's present). - * @return expression name + * + * @return expression name */ public String getName() { return name; @@ -75,5 +66,4 @@ public T accept(ExpressionNodeVisitor visitor, C context) { public String toString() { return getName(); } - } diff --git a/core/src/main/java/org/opensearch/sql/expression/aggregation/StdDevAggregator.java b/core/src/main/java/org/opensearch/sql/expression/aggregation/StdDevAggregator.java index 0cd8494449..d5422bc788 100644 --- a/core/src/main/java/org/opensearch/sql/expression/aggregation/StdDevAggregator.java +++ b/core/src/main/java/org/opensearch/sql/expression/aggregation/StdDevAggregator.java @@ -26,26 +26,18 @@ import org.opensearch.sql.expression.Expression; import org.opensearch.sql.expression.function.BuiltinFunctionName; -/** - * StandardDeviation Aggregator. - */ +/** StandardDeviation Aggregator. */ public class StdDevAggregator extends Aggregator { private final boolean isSampleStdDev; - /** - * Build Population Variance {@link VarianceAggregator}. - */ - public static Aggregator stddevPopulation(List arguments, - ExprCoreType returnType) { + /** Build Population Variance {@link VarianceAggregator}. */ + public static Aggregator stddevPopulation(List arguments, ExprCoreType returnType) { return new StdDevAggregator(false, arguments, returnType); } - /** - * Build Sample Variance {@link VarianceAggregator}. - */ - public static Aggregator stddevSample(List arguments, - ExprCoreType returnType) { + /** Build Sample Variance {@link VarianceAggregator}. */ + public static Aggregator stddevSample(List arguments, ExprCoreType returnType) { return new StdDevAggregator(true, arguments, returnType); } @@ -53,7 +45,7 @@ public static Aggregator stddevSample(List arguments, * VarianceAggregator constructor. * * @param isSampleStdDev true for sample standard deviation aggregator, false for population - * standard deviation aggregator. + * standard deviation aggregator. * @param arguments aggregator arguments. * @param returnType aggregator return types. */ @@ -74,8 +66,8 @@ public StdDevAggregator.StdDevState create() { } @Override - protected StdDevAggregator.StdDevState iterate(ExprValue value, - StdDevAggregator.StdDevState state) { + protected StdDevAggregator.StdDevState iterate( + ExprValue value, StdDevAggregator.StdDevState state) { state.evaluate(value); return state; } diff --git a/core/src/main/java/org/opensearch/sql/expression/aggregation/SumAggregator.java b/core/src/main/java/org/opensearch/sql/expression/aggregation/SumAggregator.java index f5b042034a..d637721980 100644 --- a/core/src/main/java/org/opensearch/sql/expression/aggregation/SumAggregator.java +++ b/core/src/main/java/org/opensearch/sql/expression/aggregation/SumAggregator.java @@ -3,7 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ - package org.opensearch.sql.expression.aggregation; import static org.opensearch.sql.data.model.ExprValueUtils.doubleValue; @@ -28,8 +27,8 @@ import org.opensearch.sql.expression.function.BuiltinFunctionName; /** - * The sum aggregator aggregate the value evaluated by the expression. - * If the expression evaluated result is NULL or MISSING, then the result is NULL. + * The sum aggregator aggregate the value evaluated by the expression. If the expression evaluated + * result is NULL or MISSING, then the result is NULL. */ public class SumAggregator extends Aggregator { @@ -54,9 +53,7 @@ public String toString() { return String.format(Locale.ROOT, "sum(%s)", format(getArguments())); } - /** - * Sum State. - */ + /** Sum State. */ protected static class SumState implements AggregationState { private final ExprCoreType type; @@ -69,9 +66,7 @@ protected static class SumState implements AggregationState { isEmptyCollection = true; } - /** - * Add value to current sumResult. - */ + /** Add value to current sumResult. */ public void add(ExprValue value) { switch (type) { case INTEGER: diff --git a/core/src/main/java/org/opensearch/sql/expression/aggregation/TakeAggregator.java b/core/src/main/java/org/opensearch/sql/expression/aggregation/TakeAggregator.java index cff08bb098..8791973353 100644 --- a/core/src/main/java/org/opensearch/sql/expression/aggregation/TakeAggregator.java +++ b/core/src/main/java/org/opensearch/sql/expression/aggregation/TakeAggregator.java @@ -3,7 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ - package org.opensearch.sql.expression.aggregation; import static org.opensearch.sql.utils.ExpressionUtils.format; @@ -18,8 +17,8 @@ import org.opensearch.sql.expression.function.BuiltinFunctionName; /** - * The take aggregator keeps and returns the original values of a field. - * If the field value is NULL or MISSING, then it is skipped. + * The take aggregator keeps and returns the original values of a field. If the field value is NULL + * or MISSING, then it is skipped. */ public class TakeAggregator extends Aggregator { @@ -43,9 +42,7 @@ public String toString() { return String.format(Locale.ROOT, "take(%s)", format(getArguments())); } - /** - * Take State. - */ + /** Take State. */ protected static class TakeState implements AggregationState { protected int index; protected int size; diff --git a/core/src/main/java/org/opensearch/sql/expression/aggregation/VarianceAggregator.java b/core/src/main/java/org/opensearch/sql/expression/aggregation/VarianceAggregator.java index bd9f0948f6..920830d266 100644 --- a/core/src/main/java/org/opensearch/sql/expression/aggregation/VarianceAggregator.java +++ b/core/src/main/java/org/opensearch/sql/expression/aggregation/VarianceAggregator.java @@ -26,26 +26,18 @@ import org.opensearch.sql.expression.Expression; import org.opensearch.sql.expression.function.BuiltinFunctionName; -/** - * Variance Aggregator. - */ +/** Variance Aggregator. */ public class VarianceAggregator extends Aggregator { private final boolean isSampleVariance; - /** - * Build Population Variance {@link VarianceAggregator}. - */ - public static Aggregator variancePopulation(List arguments, - ExprCoreType returnType) { + /** Build Population Variance {@link VarianceAggregator}. */ + public static Aggregator variancePopulation(List arguments, ExprCoreType returnType) { return new VarianceAggregator(false, arguments, returnType); } - /** - * Build Sample Variance {@link VarianceAggregator}. - */ - public static Aggregator varianceSample(List arguments, - ExprCoreType returnType) { + /** Build Sample Variance {@link VarianceAggregator}. */ + public static Aggregator varianceSample(List arguments, ExprCoreType returnType) { return new VarianceAggregator(true, arguments, returnType); } diff --git a/core/src/main/java/org/opensearch/sql/expression/conditional/cases/CaseClause.java b/core/src/main/java/org/opensearch/sql/expression/conditional/cases/CaseClause.java index ad7860a6dc..e18f33c6ae 100644 --- a/core/src/main/java/org/opensearch/sql/expression/conditional/cases/CaseClause.java +++ b/core/src/main/java/org/opensearch/sql/expression/conditional/cases/CaseClause.java @@ -3,7 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ - package org.opensearch.sql.expression.conditional.cases; import static org.opensearch.sql.data.type.ExprCoreType.UNDEFINED; @@ -32,19 +31,13 @@ @ToString public class CaseClause extends FunctionExpression { - /** - * List of WHEN clauses. - */ + /** List of WHEN clauses. */ private final List whenClauses; - /** - * Default result if none of WHEN conditions match. - */ + /** Default result if none of WHEN conditions match. */ private final Expression defaultResult; - /** - * Initialize case clause. - */ + /** Initialize case clause. */ public CaseClause(List whenClauses, Expression defaultResult) { super(FunctionName.of("case"), concatArgs(whenClauses, defaultResult)); this.whenClauses = whenClauses; @@ -75,15 +68,13 @@ public T accept(ExpressionNodeVisitor visitor, C context) { } /** - * Get types of each result in WHEN clause and ELSE clause. - * Exclude UNKNOWN type from NULL literal which means NULL in THEN or ELSE clause - * is not included in result. + * Get types of each result in WHEN clause and ELSE clause. Exclude UNKNOWN type from NULL literal + * which means NULL in THEN or ELSE clause is not included in result. + * * @return all result types. Use list so caller can generate friendly error message. */ public List allResultTypes() { - List types = whenClauses.stream() - .map(WhenClause::type) - .collect(Collectors.toList()); + List types = whenClauses.stream().map(WhenClause::type).collect(Collectors.toList()); if (defaultResult != null) { types.add(defaultResult.type()); } @@ -92,8 +83,8 @@ public List allResultTypes() { return types; } - private static List concatArgs(List whenClauses, - Expression defaultResult) { + private static List concatArgs( + List whenClauses, Expression defaultResult) { ImmutableList.Builder args = ImmutableList.builder(); whenClauses.forEach(args::add); @@ -102,5 +93,4 @@ private static List concatArgs(List whenClauses, } return args.build(); } - } diff --git a/core/src/main/java/org/opensearch/sql/expression/conditional/cases/WhenClause.java b/core/src/main/java/org/opensearch/sql/expression/conditional/cases/WhenClause.java index fd2eeab983..7eb731a1f2 100644 --- a/core/src/main/java/org/opensearch/sql/expression/conditional/cases/WhenClause.java +++ b/core/src/main/java/org/opensearch/sql/expression/conditional/cases/WhenClause.java @@ -3,7 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ - package org.opensearch.sql.expression.conditional.cases; import com.google.common.collect.ImmutableList; @@ -18,27 +17,19 @@ import org.opensearch.sql.expression.env.Environment; import org.opensearch.sql.expression.function.FunctionName; -/** - * WHEN clause that consists of a condition and a result corresponding. - */ +/** WHEN clause that consists of a condition and a result corresponding. */ @EqualsAndHashCode(callSuper = false) @Getter @ToString public class WhenClause extends FunctionExpression { - /** - * Condition that must be a predicate. - */ + /** Condition that must be a predicate. */ private final Expression condition; - /** - * Result to return if condition is evaluated to true. - */ + /** Result to return if condition is evaluated to true. */ private final Expression result; - /** - * Initialize when clause. - */ + /** Initialize when clause. */ public WhenClause(Expression condition, Expression result) { super(FunctionName.of("when"), ImmutableList.of(condition, result)); this.condition = condition; @@ -47,8 +38,9 @@ public WhenClause(Expression condition, Expression result) { /** * Evaluate when condition. - * @param valueEnv value env - * @return is condition satisfied + * + * @param valueEnv value env + * @return is condition satisfied */ public boolean isTrue(Environment valueEnv) { ExprValue result = condition.valueOf(valueEnv); @@ -72,5 +64,4 @@ public ExprType type() { public T accept(ExpressionNodeVisitor visitor, C context) { return visitor.visitWhen(this, context); } - } diff --git a/core/src/main/java/org/opensearch/sql/expression/datetime/CalendarLookup.java b/core/src/main/java/org/opensearch/sql/expression/datetime/CalendarLookup.java index c5b6343991..0837075f7c 100644 --- a/core/src/main/java/org/opensearch/sql/expression/datetime/CalendarLookup.java +++ b/core/src/main/java/org/opensearch/sql/expression/datetime/CalendarLookup.java @@ -3,7 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ - package org.opensearch.sql.expression.datetime; import com.google.common.collect.ImmutableList; @@ -18,6 +17,7 @@ class CalendarLookup { /** * Get a calendar for the specific mode. + * * @param mode Mode to get calendar for. * @param date Date to get calendar for. */ @@ -38,6 +38,7 @@ private static Calendar getCalendar(int mode, LocalDate date) { /** * Set first day of week, minimal days in first week and date in calendar. + * * @param firstDayOfWeek the given first day of the week. * @param minimalDaysInWeek the given minimal days required in the first week of the year. * @param date the given date. @@ -52,6 +53,7 @@ private static Calendar getCalendar(int firstDayOfWeek, int minimalDaysInWeek, L /** * Returns week number for date according to mode. + * * @param mode Integer for mode. Valid mode values are 0 to 7. * @param date LocalDate for date. */ @@ -68,6 +70,7 @@ static int getWeekNumber(int mode, LocalDate date) { /** * Returns year for date according to mode. + * * @param mode Integer for mode. Valid mode values are 0 to 7. * @param date LocalDate for date. */ diff --git a/core/src/main/java/org/opensearch/sql/expression/datetime/DateTimeFormatterUtil.java b/core/src/main/java/org/opensearch/sql/expression/datetime/DateTimeFormatterUtil.java index 55bfa67f3f..339ebe4b2d 100644 --- a/core/src/main/java/org/opensearch/sql/expression/datetime/DateTimeFormatterUtil.java +++ b/core/src/main/java/org/opensearch/sql/expression/datetime/DateTimeFormatterUtil.java @@ -28,8 +28,8 @@ import org.opensearch.sql.expression.function.FunctionProperties; /** - * This class converts a SQL style DATE_FORMAT format specifier and converts it to a - * Java SimpleDateTime format. + * This class converts a SQL style DATE_FORMAT format specifier and converts it to a Java + * SimpleDateTime format. */ class DateTimeFormatterUtil { private static final int SUFFIX_SPECIAL_START_TH = 11; @@ -39,8 +39,7 @@ class DateTimeFormatterUtil { private static final String NANO_SEC_FORMAT = "'%06d'"; private static final Map SUFFIX_CONVERTER = - ImmutableMap.builder() - .put(1, "st").put(2, "nd").put(3, "rd").build(); + ImmutableMap.builder().put(1, "st").put(2, "nd").put(3, "rd").build(); // The following have special cases that need handling outside of the format options provided // by the DateTimeFormatter class. @@ -50,52 +49,70 @@ interface DateTimeFormatHandler { private static final Map DATE_HANDLERS = ImmutableMap.builder() - .put("%a", (date) -> "EEE") // %a => EEE - Abbreviated weekday name (Sun..Sat) - .put("%b", (date) -> "LLL") // %b => LLL - Abbreviated month name (Jan..Dec) - .put("%c", (date) -> "MM") // %c => MM - Month, numeric (0..12) - .put("%d", (date) -> "dd") // %d => dd - Day of the month, numeric (00..31) - .put("%e", (date) -> "d") // %e => d - Day of the month, numeric (0..31) - .put("%H", (date) -> "HH") // %H => HH - (00..23) - .put("%h", (date) -> "hh") // %h => hh - (01..12) - .put("%I", (date) -> "hh") // %I => hh - (01..12) - .put("%i", (date) -> "mm") // %i => mm - Minutes, numeric (00..59) - .put("%j", (date) -> "DDD") // %j => DDD - (001..366) - .put("%k", (date) -> "H") // %k => H - (0..23) - .put("%l", (date) -> "h") // %l => h - (1..12) - .put("%p", (date) -> "a") // %p => a - AM or PM - .put("%M", (date) -> "LLLL") // %M => LLLL - Month name (January..December) - .put("%m", (date) -> "MM") // %m => MM - Month, numeric (00..12) - .put("%r", (date) -> "hh:mm:ss a") // %r => hh:mm:ss a - hh:mm:ss followed by AM or PM - .put("%S", (date) -> "ss") // %S => ss - Seconds (00..59) - .put("%s", (date) -> "ss") // %s => ss - Seconds (00..59) - .put("%T", (date) -> "HH:mm:ss") // %T => HH:mm:ss - .put("%W", (date) -> "EEEE") // %W => EEEE - Weekday name (Sunday..Saturday) - .put("%Y", (date) -> "yyyy") // %Y => yyyy - Year, numeric, 4 digits - .put("%y", (date) -> "yy") // %y => yy - Year, numeric, 2 digits - // The following are not directly supported by DateTimeFormatter. - .put("%D", (date) -> // %w - Day of month with English suffix - String.format("'%d%s'", date.getDayOfMonth(), getSuffix(date.getDayOfMonth()))) - .put("%f", (date) -> // %f - Microseconds - String.format(NANO_SEC_FORMAT, (date.getNano() / 1000))) - .put("%w", (date) -> // %w - Day of week (0 indexed) - String.format("'%d'", date.getDayOfWeek().getValue())) - .put("%U", (date) -> // %U Week where Sunday is the first day - WEEK() mode 0 - String.format("'%d'", CalendarLookup.getWeekNumber(0, date.toLocalDate()))) - .put("%u", (date) -> // %u Week where Monday is the first day - WEEK() mode 1 - String.format("'%d'", CalendarLookup.getWeekNumber(1, date.toLocalDate()))) - .put("%V", (date) -> // %V Week where Sunday is the first day - WEEK() mode 2 used with %X - String.format("'%d'", CalendarLookup.getWeekNumber(2, date.toLocalDate()))) - .put("%v", (date) -> // %v Week where Monday is the first day - WEEK() mode 3 used with %x - String.format("'%d'", CalendarLookup.getWeekNumber(3, date.toLocalDate()))) - .put("%X", (date) -> // %X Year for week where Sunday is the first day, 4 digits used with %V - String.format("'%d'", CalendarLookup.getYearNumber(2, date.toLocalDate()))) - .put("%x", (date) -> // %x Year for week where Monday is the first day, 4 digits used with %v - String.format("'%d'", CalendarLookup.getYearNumber(3, date.toLocalDate()))) - .build(); - - //Handlers for the time_format function. - //Some format specifiers return 0 or null to align with MySQL. - //https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_time-format + .put("%a", (date) -> "EEE") // %a => EEE - Abbreviated weekday name (Sun..Sat) + .put("%b", (date) -> "LLL") // %b => LLL - Abbreviated month name (Jan..Dec) + .put("%c", (date) -> "MM") // %c => MM - Month, numeric (0..12) + .put("%d", (date) -> "dd") // %d => dd - Day of the month, numeric (00..31) + .put("%e", (date) -> "d") // %e => d - Day of the month, numeric (0..31) + .put("%H", (date) -> "HH") // %H => HH - (00..23) + .put("%h", (date) -> "hh") // %h => hh - (01..12) + .put("%I", (date) -> "hh") // %I => hh - (01..12) + .put("%i", (date) -> "mm") // %i => mm - Minutes, numeric (00..59) + .put("%j", (date) -> "DDD") // %j => DDD - (001..366) + .put("%k", (date) -> "H") // %k => H - (0..23) + .put("%l", (date) -> "h") // %l => h - (1..12) + .put("%p", (date) -> "a") // %p => a - AM or PM + .put("%M", (date) -> "LLLL") // %M => LLLL - Month name (January..December) + .put("%m", (date) -> "MM") // %m => MM - Month, numeric (00..12) + .put("%r", (date) -> "hh:mm:ss a") // %r => hh:mm:ss a - hh:mm:ss followed by AM or PM + .put("%S", (date) -> "ss") // %S => ss - Seconds (00..59) + .put("%s", (date) -> "ss") // %s => ss - Seconds (00..59) + .put("%T", (date) -> "HH:mm:ss") // %T => HH:mm:ss + .put("%W", (date) -> "EEEE") // %W => EEEE - Weekday name (Sunday..Saturday) + .put("%Y", (date) -> "yyyy") // %Y => yyyy - Year, numeric, 4 digits + .put("%y", (date) -> "yy") // %y => yy - Year, numeric, 2 digits + // The following are not directly supported by DateTimeFormatter. + .put( + "%D", + (date) -> // %w - Day of month with English suffix + String.format("'%d%s'", date.getDayOfMonth(), getSuffix(date.getDayOfMonth()))) + .put( + "%f", + (date) -> // %f - Microseconds + String.format(NANO_SEC_FORMAT, (date.getNano() / 1000))) + .put( + "%w", + (date) -> // %w - Day of week (0 indexed) + String.format("'%d'", date.getDayOfWeek().getValue())) + .put( + "%U", + (date) -> // %U Week where Sunday is the first day - WEEK() mode 0 + String.format("'%d'", CalendarLookup.getWeekNumber(0, date.toLocalDate()))) + .put( + "%u", + (date) -> // %u Week where Monday is the first day - WEEK() mode 1 + String.format("'%d'", CalendarLookup.getWeekNumber(1, date.toLocalDate()))) + .put( + "%V", + (date) -> // %V Week where Sunday is the first day - WEEK() mode 2 used with %X + String.format("'%d'", CalendarLookup.getWeekNumber(2, date.toLocalDate()))) + .put( + "%v", + (date) -> // %v Week where Monday is the first day - WEEK() mode 3 used with %x + String.format("'%d'", CalendarLookup.getWeekNumber(3, date.toLocalDate()))) + .put( + "%X", + (date) -> // %X Year for week where Sunday is the first day, 4 digits used with %V + String.format("'%d'", CalendarLookup.getYearNumber(2, date.toLocalDate()))) + .put( + "%x", + (date) -> // %x Year for week where Monday is the first day, 4 digits used with %v + String.format("'%d'", CalendarLookup.getYearNumber(3, date.toLocalDate()))) + .build(); + + // Handlers for the time_format function. + // Some format specifiers return 0 or null to align with MySQL. + // https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_time-format private static final Map TIME_HANDLERS = ImmutableMap.builder() .put("%a", (date) -> null) @@ -121,7 +138,9 @@ interface DateTimeFormatHandler { .put("%Y", (date) -> "0000") .put("%y", (date) -> "00") .put("%D", (date) -> null) - .put("%f", (date) -> // %f - Microseconds + .put( + "%f", + (date) -> // %f - Microseconds String.format(NANO_SEC_FORMAT, (date.getNano() / 1000))) .put("%w", (date) -> null) .put("%U", (date) -> null) @@ -157,7 +176,7 @@ interface DateTimeFormatHandler { .put("%Y", "u") // %Y => yyyy - Year, numeric, 4 digits .put("%y", "u") // %y => yy - Year, numeric, 2 digits .put("%f", "n") // %f => n - Nanoseconds - //The following have been implemented but cannot be aligned with + // The following have been implemented but cannot be aligned with // MySQL due to the limitations of the DatetimeFormatter .put("%D", "d") // %w - Day of month with English suffix .put("%w", "e") // %w - Day of week (0 indexed) @@ -170,20 +189,19 @@ interface DateTimeFormatHandler { .build(); private static final Pattern pattern = Pattern.compile("%."); - private static final Pattern CHARACTERS_WITH_NO_MOD_LITERAL_BEHIND_PATTERN - = Pattern.compile("(? handler, - LocalDateTime datetime) { + static ExprValue getFormattedString( + ExprValue formatExpr, Map handler, LocalDateTime datetime) { StringBuffer cleanFormat = getCleanFormat(formatExpr); final Matcher matcher = pattern.matcher(cleanFormat.toString()); final StringBuffer format = new StringBuffer(); try { while (matcher.find()) { - matcher.appendReplacement(format, - handler.getOrDefault(matcher.group(), (d) -> - String.format("'%s'", matcher.group().replaceFirst(MOD_LITERAL, ""))) + matcher.appendReplacement( + format, + handler + .getOrDefault( + matcher.group(), + (d) -> String.format("'%s'", matcher.group().replaceFirst(MOD_LITERAL, ""))) .getFormat(datetime)); } } catch (Exception e) { @@ -219,12 +240,13 @@ static ExprValue getFormattedString(ExprValue formatExpr, // English Locale matches SQL requirements. // 'AM'/'PM' instead of 'a.m.'/'p.m.' // 'Sat' instead of 'Sat.' etc - return new ExprStringValue(datetime.format( - DateTimeFormatter.ofPattern(format.toString(), Locale.ENGLISH))); + return new ExprStringValue( + datetime.format(DateTimeFormatter.ofPattern(format.toString(), Locale.ENGLISH))); } /** * Format the date using the date format String. + * * @param dateExpr the date ExprValue of Date/Datetime/Timestamp/String type. * @param formatExpr the format ExprValue of String type. * @return Date formatted using format and returned as a String. @@ -242,13 +264,14 @@ static ExprValue getFormattedDateOfToday(ExprValue formatExpr, ExprValue time, C /** * Format the date using the date format String. + * * @param timeExpr the date ExprValue of Date/Datetime/Timestamp/String type. * @param formatExpr the format ExprValue of String type. * @return Date formatted using format and returned as a String. */ static ExprValue getFormattedTime(ExprValue timeExpr, ExprValue formatExpr) { - //Initializes DateTime with LocalDate.now(). This is safe because the date is ignored. - //The time_format function will only return 0 or null for invalid string format specifiers. + // Initializes DateTime with LocalDate.now(). This is safe because the date is ignored. + // The time_format function will only return 0 or null for invalid string format specifiers. final LocalDateTime time = LocalDateTime.of(LocalDate.now(), timeExpr.timeValue()); return getFormattedString(formatExpr, TIME_HANDLERS, time); @@ -266,30 +289,33 @@ private static boolean canGetTime(TemporalAccessor ta) { && ta.isSupported(ChronoField.SECOND_OF_MINUTE)); } - static ExprValue parseStringWithDateOrTime(FunctionProperties fp, - ExprValue datetimeStringExpr, - ExprValue formatExpr) { + static ExprValue parseStringWithDateOrTime( + FunctionProperties fp, ExprValue datetimeStringExpr, ExprValue formatExpr) { - //Replace patterns with % for Java DateTimeFormatter + // Replace patterns with % for Java DateTimeFormatter StringBuffer cleanFormat = getCleanFormat(formatExpr); final Matcher matcher = pattern.matcher(cleanFormat.toString()); final StringBuffer format = new StringBuffer(); while (matcher.find()) { - matcher.appendReplacement(format, - STR_TO_DATE_FORMATS.getOrDefault(matcher.group(), + matcher.appendReplacement( + format, + STR_TO_DATE_FORMATS.getOrDefault( + matcher.group(), String.format("'%s'", matcher.group().replaceFirst(MOD_LITERAL, "")))); } matcher.appendTail(format); TemporalAccessor taWithMissingFields; - //Return NULL for invalid parse in string to align with MySQL + // Return NULL for invalid parse in string to align with MySQL try { - //Get Temporal Accessor to initially parse string without default values - taWithMissingFields = new DateTimeFormatterBuilder() - .appendPattern(format.toString()) - .toFormatter().withResolverStyle(ResolverStyle.STRICT) - .parseUnresolved(datetimeStringExpr.stringValue(), new ParsePosition(0)); + // Get Temporal Accessor to initially parse string without default values + taWithMissingFields = + new DateTimeFormatterBuilder() + .appendPattern(format.toString()) + .toFormatter() + .withResolverStyle(ResolverStyle.STRICT) + .parseUnresolved(datetimeStringExpr.stringValue(), new ParsePosition(0)); if (taWithMissingFields == null) { throw new DateTimeException("Input string could not be parsed properly."); } @@ -300,31 +326,42 @@ static ExprValue parseStringWithDateOrTime(FunctionProperties fp, return ExprNullValue.of(); } - int year = taWithMissingFields.isSupported(ChronoField.YEAR) - ? taWithMissingFields.get(ChronoField.YEAR) : 2000; - - int month = taWithMissingFields.isSupported(ChronoField.MONTH_OF_YEAR) - ? taWithMissingFields.get(ChronoField.MONTH_OF_YEAR) : 1; - - int day = taWithMissingFields.isSupported(ChronoField.DAY_OF_MONTH) - ? taWithMissingFields.get(ChronoField.DAY_OF_MONTH) : 1; - - int hour = taWithMissingFields.isSupported(ChronoField.HOUR_OF_DAY) - ? taWithMissingFields.get(ChronoField.HOUR_OF_DAY) : 0; - - int minute = taWithMissingFields.isSupported(ChronoField.MINUTE_OF_HOUR) - ? taWithMissingFields.get(ChronoField.MINUTE_OF_HOUR) : 0; - - int second = taWithMissingFields.isSupported(ChronoField.SECOND_OF_MINUTE) - ? taWithMissingFields.get(ChronoField.SECOND_OF_MINUTE) : 0; - - //Fill returned datetime with current date if only Time information was parsed + int year = + taWithMissingFields.isSupported(ChronoField.YEAR) + ? taWithMissingFields.get(ChronoField.YEAR) + : 2000; + + int month = + taWithMissingFields.isSupported(ChronoField.MONTH_OF_YEAR) + ? taWithMissingFields.get(ChronoField.MONTH_OF_YEAR) + : 1; + + int day = + taWithMissingFields.isSupported(ChronoField.DAY_OF_MONTH) + ? taWithMissingFields.get(ChronoField.DAY_OF_MONTH) + : 1; + + int hour = + taWithMissingFields.isSupported(ChronoField.HOUR_OF_DAY) + ? taWithMissingFields.get(ChronoField.HOUR_OF_DAY) + : 0; + + int minute = + taWithMissingFields.isSupported(ChronoField.MINUTE_OF_HOUR) + ? taWithMissingFields.get(ChronoField.MINUTE_OF_HOUR) + : 0; + + int second = + taWithMissingFields.isSupported(ChronoField.SECOND_OF_MINUTE) + ? taWithMissingFields.get(ChronoField.SECOND_OF_MINUTE) + : 0; + + // Fill returned datetime with current date if only Time information was parsed LocalDateTime output; if (!canGetDate(taWithMissingFields)) { - output = LocalDateTime.of( - LocalDate.now(fp.getQueryStartClock()), - LocalTime.of(hour, minute, second) - ); + output = + LocalDateTime.of( + LocalDate.now(fp.getQueryStartClock()), LocalTime.of(hour, minute, second)); } else { output = LocalDateTime.of(year, month, day, hour, minute, second); } @@ -334,6 +371,7 @@ static ExprValue parseStringWithDateOrTime(FunctionProperties fp, /** * Returns English suffix of incoming value. + * * @param val Incoming value. * @return English suffix as String (st, nd, rd, th) */ diff --git a/core/src/main/java/org/opensearch/sql/expression/datetime/DateTimeFunction.java b/core/src/main/java/org/opensearch/sql/expression/datetime/DateTimeFunction.java index cd5ef23d1c..84c670cb1c 100644 --- a/core/src/main/java/org/opensearch/sql/expression/datetime/DateTimeFunction.java +++ b/core/src/main/java/org/opensearch/sql/expression/datetime/DateTimeFunction.java @@ -3,10 +3,8 @@ * SPDX-License-Identifier: Apache-2.0 */ - package org.opensearch.sql.expression.datetime; - import static java.time.temporal.ChronoUnit.DAYS; import static java.time.temporal.ChronoUnit.HOURS; import static java.time.temporal.ChronoUnit.MICROS; @@ -100,14 +98,13 @@ import org.opensearch.sql.utils.DateTimeUtils; /** - * The definition of date and time functions. - * 1) have the clear interface for function define. - * 2) the implementation should rely on ExprValue. + * The definition of date and time functions. 1) have the clear interface for function define. 2) + * the implementation should rely on ExprValue. */ @UtilityClass @SuppressWarnings("unchecked") public class DateTimeFunction { - //The number of seconds per day + // The number of seconds per day public static final long SECONDS_PER_DAY = 86400; // The number of days from year zero to year 1970. @@ -254,11 +251,12 @@ public void register(BuiltinFunctionRepository repository) { * `now(y) return different values. */ private FunctionResolver now(FunctionName functionName) { - return define(functionName, + return define( + functionName, implWithProperties( - functionProperties -> new ExprDatetimeValue( - formatNow(functionProperties.getQueryStartClock())), DATETIME) - ); + functionProperties -> + new ExprDatetimeValue(formatNow(functionProperties.getQueryStartClock())), + DATETIME)); } private FunctionResolver now() { @@ -277,25 +275,28 @@ private FunctionResolver localtime() { return now(BuiltinFunctionName.LOCALTIME.getName()); } - /** - * SYSDATE() returns the time at which it executes. - */ + /** SYSDATE() returns the time at which it executes. */ private FunctionResolver sysdate() { - return define(BuiltinFunctionName.SYSDATE.getName(), - implWithProperties(functionProperties - -> new ExprDatetimeValue(formatNow(Clock.systemDefaultZone())), DATETIME), - FunctionDSL.implWithProperties((functionProperties, v) -> new ExprDatetimeValue( - formatNow(Clock.systemDefaultZone(), v.integerValue())), DATETIME, INTEGER) - ); + return define( + BuiltinFunctionName.SYSDATE.getName(), + implWithProperties( + functionProperties -> new ExprDatetimeValue(formatNow(Clock.systemDefaultZone())), + DATETIME), + FunctionDSL.implWithProperties( + (functionProperties, v) -> + new ExprDatetimeValue(formatNow(Clock.systemDefaultZone(), v.integerValue())), + DATETIME, + INTEGER)); } - /** - * Synonym for @see `now`. - */ + /** Synonym for @see `now`. */ private FunctionResolver curtime(FunctionName functionName) { - return define(functionName, - implWithProperties(functionProperties -> new ExprTimeValue( - formatNow(functionProperties.getQueryStartClock()).toLocalTime()), TIME)); + return define( + functionName, + implWithProperties( + functionProperties -> + new ExprTimeValue(formatNow(functionProperties.getQueryStartClock()).toLocalTime()), + TIME)); } private FunctionResolver curtime() { @@ -307,9 +308,12 @@ private FunctionResolver current_time() { } private FunctionResolver curdate(FunctionName functionName) { - return define(functionName, - implWithProperties(functionProperties -> new ExprDateValue( - formatNow(functionProperties.getQueryStartClock()).toLocalDate()), DATE)); + return define( + functionName, + implWithProperties( + functionProperties -> + new ExprDateValue(formatNow(functionProperties.getQueryStartClock()).toLocalDate()), + DATE)); } private FunctionResolver curdate() { @@ -321,33 +325,27 @@ private FunctionResolver current_date() { } /** - * A common signature for `date_add` and `date_sub`. - * Specify a start date and add/subtract a temporal amount to/from the date. - * The return type depends on the date type and the interval unit. Detailed supported signatures: - * (DATE/DATETIME/TIMESTAMP/TIME, INTERVAL) -> DATETIME - * MySQL has these signatures too - * (DATE, INTERVAL) -> DATE // when interval has no time part - * (TIME, INTERVAL) -> TIME // when interval has no date part - * (STRING, INTERVAL) -> STRING // when argument has date or datetime string, - * // result has date or datetime depending on interval type + * A common signature for `date_add` and `date_sub`. Specify a start date and add/subtract a + * temporal amount to/from the date. The return type depends on the date type and the interval + * unit. Detailed supported signatures: (DATE/DATETIME/TIMESTAMP/TIME, INTERVAL) -> DATETIME MySQL + * has these signatures too (DATE, INTERVAL) -> DATE // when interval has no time part (TIME, + * INTERVAL) -> TIME // when interval has no date part (STRING, INTERVAL) -> STRING // when + * argument has date or datetime string, // result has date or datetime depending on interval type */ private Stream> get_date_add_date_sub_signatures( SerializableTriFunction function) { return Stream.of( implWithProperties(nullMissingHandlingWithProperties(function), DATETIME, DATE, INTERVAL), - implWithProperties(nullMissingHandlingWithProperties(function), - DATETIME, DATETIME, INTERVAL), - implWithProperties(nullMissingHandlingWithProperties(function), - DATETIME, TIMESTAMP, INTERVAL), - implWithProperties(nullMissingHandlingWithProperties(function), DATETIME, TIME, INTERVAL) - ); + implWithProperties( + nullMissingHandlingWithProperties(function), DATETIME, DATETIME, INTERVAL), + implWithProperties( + nullMissingHandlingWithProperties(function), DATETIME, TIMESTAMP, INTERVAL), + implWithProperties(nullMissingHandlingWithProperties(function), DATETIME, TIME, INTERVAL)); } /** - * A common signature for `adddate` and `subdate`. - * Adds/subtracts an integer number of days to/from the first argument. - * (DATE, LONG) -> DATE - * (TIME/DATETIME/TIMESTAMP, LONG) -> DATETIME + * A common signature for `adddate` and `subdate`. Adds/subtracts an integer number of days + * to/from the first argument. (DATE, LONG) -> DATE (TIME/DATETIME/TIMESTAMP, LONG) -> DATETIME */ private Stream> get_adddate_subdate_signatures( SerializableTriFunction function) { @@ -355,87 +353,124 @@ private FunctionResolver current_date() { implWithProperties(nullMissingHandlingWithProperties(function), DATE, DATE, LONG), implWithProperties(nullMissingHandlingWithProperties(function), DATETIME, DATETIME, LONG), implWithProperties(nullMissingHandlingWithProperties(function), DATETIME, TIMESTAMP, LONG), - implWithProperties(nullMissingHandlingWithProperties(function), DATETIME, TIME, LONG) - ); + implWithProperties(nullMissingHandlingWithProperties(function), DATETIME, TIME, LONG)); } private DefaultFunctionResolver adddate() { - return define(BuiltinFunctionName.ADDDATE.getName(), + return define( + BuiltinFunctionName.ADDDATE.getName(), (SerializableFunction>[]) (Stream.concat( - get_date_add_date_sub_signatures(DateTimeFunction::exprAddDateInterval), - get_adddate_subdate_signatures(DateTimeFunction::exprAddDateDays)) + get_date_add_date_sub_signatures(DateTimeFunction::exprAddDateInterval), + get_adddate_subdate_signatures(DateTimeFunction::exprAddDateDays)) .toArray(SerializableFunction[]::new))); } /** - * Adds expr2 to expr1 and returns the result. - * (TIME, TIME/DATE/DATETIME/TIMESTAMP) -> TIME - * (DATE/DATETIME/TIMESTAMP, TIME/DATE/DATETIME/TIMESTAMP) -> DATETIME - * TODO: MySQL has these signatures too - * (STRING, STRING/TIME) -> STRING // second arg - string with time only - * (x, STRING) -> NULL // second arg - string with timestamp - * (x, STRING/DATE) -> x // second arg - string with date only + * Adds expr2 to expr1 and returns the result. (TIME, TIME/DATE/DATETIME/TIMESTAMP) -> TIME + * (DATE/DATETIME/TIMESTAMP, TIME/DATE/DATETIME/TIMESTAMP) -> DATETIME TODO: MySQL has these + * signatures too (STRING, STRING/TIME) -> STRING // second arg - string with time only (x, + * STRING) -> NULL // second arg - string with timestamp (x, STRING/DATE) -> x // second arg - + * string with date only */ private DefaultFunctionResolver addtime() { - return define(BuiltinFunctionName.ADDTIME.getName(), - implWithProperties(nullMissingHandlingWithProperties(DateTimeFunction::exprAddTime), - TIME, TIME, TIME), - implWithProperties(nullMissingHandlingWithProperties(DateTimeFunction::exprAddTime), - TIME, TIME, DATE), - implWithProperties(nullMissingHandlingWithProperties(DateTimeFunction::exprAddTime), - TIME, TIME, DATETIME), - implWithProperties(nullMissingHandlingWithProperties(DateTimeFunction::exprAddTime), - TIME, TIME, TIMESTAMP), - implWithProperties(nullMissingHandlingWithProperties(DateTimeFunction::exprAddTime), - DATETIME, DATETIME, TIME), - implWithProperties(nullMissingHandlingWithProperties(DateTimeFunction::exprAddTime), - DATETIME, DATETIME, DATE), - implWithProperties(nullMissingHandlingWithProperties(DateTimeFunction::exprAddTime), - DATETIME, DATETIME, DATETIME), - implWithProperties(nullMissingHandlingWithProperties(DateTimeFunction::exprAddTime), - DATETIME, DATETIME, TIMESTAMP), - implWithProperties(nullMissingHandlingWithProperties(DateTimeFunction::exprAddTime), - DATETIME, DATE, TIME), - implWithProperties(nullMissingHandlingWithProperties(DateTimeFunction::exprAddTime), - DATETIME, DATE, DATE), - implWithProperties(nullMissingHandlingWithProperties(DateTimeFunction::exprAddTime), - DATETIME, DATE, DATETIME), - implWithProperties(nullMissingHandlingWithProperties(DateTimeFunction::exprAddTime), - DATETIME, DATE, TIMESTAMP), - implWithProperties(nullMissingHandlingWithProperties(DateTimeFunction::exprAddTime), - DATETIME, TIMESTAMP, TIME), - implWithProperties(nullMissingHandlingWithProperties(DateTimeFunction::exprAddTime), - DATETIME, TIMESTAMP, DATE), - implWithProperties(nullMissingHandlingWithProperties(DateTimeFunction::exprAddTime), - DATETIME, TIMESTAMP, DATETIME), - implWithProperties(nullMissingHandlingWithProperties(DateTimeFunction::exprAddTime), - DATETIME, TIMESTAMP, TIMESTAMP) - ); - } - - /** - * Converts date/time from a specified timezone to another specified timezone. - * The supported signatures: - * (DATETIME, STRING, STRING) -> DATETIME - * (STRING, STRING, STRING) -> DATETIME - */ - private DefaultFunctionResolver convert_tz() { - return define(BuiltinFunctionName.CONVERT_TZ.getName(), - impl(nullMissingHandling(DateTimeFunction::exprConvertTZ), - DATETIME, DATETIME, STRING, STRING), - impl(nullMissingHandling(DateTimeFunction::exprConvertTZ), - DATETIME, STRING, STRING, STRING) - ); + return define( + BuiltinFunctionName.ADDTIME.getName(), + implWithProperties( + nullMissingHandlingWithProperties(DateTimeFunction::exprAddTime), TIME, TIME, TIME), + implWithProperties( + nullMissingHandlingWithProperties(DateTimeFunction::exprAddTime), TIME, TIME, DATE), + implWithProperties( + nullMissingHandlingWithProperties(DateTimeFunction::exprAddTime), TIME, TIME, DATETIME), + implWithProperties( + nullMissingHandlingWithProperties(DateTimeFunction::exprAddTime), + TIME, + TIME, + TIMESTAMP), + implWithProperties( + nullMissingHandlingWithProperties(DateTimeFunction::exprAddTime), + DATETIME, + DATETIME, + TIME), + implWithProperties( + nullMissingHandlingWithProperties(DateTimeFunction::exprAddTime), + DATETIME, + DATETIME, + DATE), + implWithProperties( + nullMissingHandlingWithProperties(DateTimeFunction::exprAddTime), + DATETIME, + DATETIME, + DATETIME), + implWithProperties( + nullMissingHandlingWithProperties(DateTimeFunction::exprAddTime), + DATETIME, + DATETIME, + TIMESTAMP), + implWithProperties( + nullMissingHandlingWithProperties(DateTimeFunction::exprAddTime), DATETIME, DATE, TIME), + implWithProperties( + nullMissingHandlingWithProperties(DateTimeFunction::exprAddTime), DATETIME, DATE, DATE), + implWithProperties( + nullMissingHandlingWithProperties(DateTimeFunction::exprAddTime), + DATETIME, + DATE, + DATETIME), + implWithProperties( + nullMissingHandlingWithProperties(DateTimeFunction::exprAddTime), + DATETIME, + DATE, + TIMESTAMP), + implWithProperties( + nullMissingHandlingWithProperties(DateTimeFunction::exprAddTime), + DATETIME, + TIMESTAMP, + TIME), + implWithProperties( + nullMissingHandlingWithProperties(DateTimeFunction::exprAddTime), + DATETIME, + TIMESTAMP, + DATE), + implWithProperties( + nullMissingHandlingWithProperties(DateTimeFunction::exprAddTime), + DATETIME, + TIMESTAMP, + DATETIME), + implWithProperties( + nullMissingHandlingWithProperties(DateTimeFunction::exprAddTime), + DATETIME, + TIMESTAMP, + TIMESTAMP)); } /** - * Extracts the date part of a date and time value. - * Also to construct a date type. The supported signatures: - * STRING/DATE/DATETIME/TIMESTAMP -> DATE + * Converts date/time from a specified timezone to another specified timezone. The supported + * signatures: (DATETIME, STRING, STRING) -> DATETIME (STRING, STRING, STRING) -> DATETIME + */ + private DefaultFunctionResolver convert_tz() { + return define( + BuiltinFunctionName.CONVERT_TZ.getName(), + impl( + nullMissingHandling(DateTimeFunction::exprConvertTZ), + DATETIME, + DATETIME, + STRING, + STRING), + impl( + nullMissingHandling(DateTimeFunction::exprConvertTZ), + DATETIME, + STRING, + STRING, + STRING)); + } + + /** + * Extracts the date part of a date and time value. Also to construct a date type. The supported + * signatures: STRING/DATE/DATETIME/TIMESTAMP -> DATE */ private DefaultFunctionResolver date() { - return define(BuiltinFunctionName.DATE.getName(), + return define( + BuiltinFunctionName.DATE.getName(), impl(nullMissingHandling(DateTimeFunction::exprDate), DATE, STRING), impl(nullMissingHandling(DateTimeFunction::exprDate), DATE, DATE), impl(nullMissingHandling(DateTimeFunction::exprDate), DATE, DATETIME), @@ -447,273 +482,308 @@ private DefaultFunctionResolver date() { * (DATE/DATETIME/TIMESTAMP/TIME, DATE/DATETIME/TIMESTAMP/TIME) -> LONG */ private DefaultFunctionResolver datediff() { - return define(BuiltinFunctionName.DATEDIFF.getName(), - implWithProperties(nullMissingHandlingWithProperties(DateTimeFunction::exprDateDiff), - LONG, DATE, DATE), - implWithProperties(nullMissingHandlingWithProperties(DateTimeFunction::exprDateDiff), - LONG, DATETIME, DATE), - implWithProperties(nullMissingHandlingWithProperties(DateTimeFunction::exprDateDiff), - LONG, DATE, DATETIME), - implWithProperties(nullMissingHandlingWithProperties(DateTimeFunction::exprDateDiff), - LONG, DATETIME, DATETIME), - implWithProperties(nullMissingHandlingWithProperties(DateTimeFunction::exprDateDiff), - LONG, DATE, TIME), - implWithProperties(nullMissingHandlingWithProperties(DateTimeFunction::exprDateDiff), - LONG, TIME, DATE), - implWithProperties(nullMissingHandlingWithProperties(DateTimeFunction::exprDateDiff), - LONG, TIME, TIME), - implWithProperties(nullMissingHandlingWithProperties(DateTimeFunction::exprDateDiff), - LONG, TIMESTAMP, DATE), - implWithProperties(nullMissingHandlingWithProperties(DateTimeFunction::exprDateDiff), - LONG, DATE, TIMESTAMP), - implWithProperties(nullMissingHandlingWithProperties(DateTimeFunction::exprDateDiff), - LONG, TIMESTAMP, TIMESTAMP), - implWithProperties(nullMissingHandlingWithProperties(DateTimeFunction::exprDateDiff), - LONG, TIMESTAMP, TIME), - implWithProperties(nullMissingHandlingWithProperties(DateTimeFunction::exprDateDiff), - LONG, TIME, TIMESTAMP), - implWithProperties(nullMissingHandlingWithProperties(DateTimeFunction::exprDateDiff), - LONG, TIMESTAMP, DATETIME), - implWithProperties(nullMissingHandlingWithProperties(DateTimeFunction::exprDateDiff), - LONG, DATETIME, TIMESTAMP), - implWithProperties(nullMissingHandlingWithProperties(DateTimeFunction::exprDateDiff), - LONG, TIME, DATETIME), - implWithProperties(nullMissingHandlingWithProperties(DateTimeFunction::exprDateDiff), - LONG, DATETIME, TIME)); - } - - /** - * Specify a datetime with time zone field and a time zone to convert to. - * Returns a local date time. - * (STRING, STRING) -> DATETIME - * (STRING) -> DATETIME + return define( + BuiltinFunctionName.DATEDIFF.getName(), + implWithProperties( + nullMissingHandlingWithProperties(DateTimeFunction::exprDateDiff), LONG, DATE, DATE), + implWithProperties( + nullMissingHandlingWithProperties(DateTimeFunction::exprDateDiff), + LONG, + DATETIME, + DATE), + implWithProperties( + nullMissingHandlingWithProperties(DateTimeFunction::exprDateDiff), + LONG, + DATE, + DATETIME), + implWithProperties( + nullMissingHandlingWithProperties(DateTimeFunction::exprDateDiff), + LONG, + DATETIME, + DATETIME), + implWithProperties( + nullMissingHandlingWithProperties(DateTimeFunction::exprDateDiff), LONG, DATE, TIME), + implWithProperties( + nullMissingHandlingWithProperties(DateTimeFunction::exprDateDiff), LONG, TIME, DATE), + implWithProperties( + nullMissingHandlingWithProperties(DateTimeFunction::exprDateDiff), LONG, TIME, TIME), + implWithProperties( + nullMissingHandlingWithProperties(DateTimeFunction::exprDateDiff), + LONG, + TIMESTAMP, + DATE), + implWithProperties( + nullMissingHandlingWithProperties(DateTimeFunction::exprDateDiff), + LONG, + DATE, + TIMESTAMP), + implWithProperties( + nullMissingHandlingWithProperties(DateTimeFunction::exprDateDiff), + LONG, + TIMESTAMP, + TIMESTAMP), + implWithProperties( + nullMissingHandlingWithProperties(DateTimeFunction::exprDateDiff), + LONG, + TIMESTAMP, + TIME), + implWithProperties( + nullMissingHandlingWithProperties(DateTimeFunction::exprDateDiff), + LONG, + TIME, + TIMESTAMP), + implWithProperties( + nullMissingHandlingWithProperties(DateTimeFunction::exprDateDiff), + LONG, + TIMESTAMP, + DATETIME), + implWithProperties( + nullMissingHandlingWithProperties(DateTimeFunction::exprDateDiff), + LONG, + DATETIME, + TIMESTAMP), + implWithProperties( + nullMissingHandlingWithProperties(DateTimeFunction::exprDateDiff), + LONG, + TIME, + DATETIME), + implWithProperties( + nullMissingHandlingWithProperties(DateTimeFunction::exprDateDiff), + LONG, + DATETIME, + TIME)); + } + + /** + * Specify a datetime with time zone field and a time zone to convert to. Returns a local date + * time. (STRING, STRING) -> DATETIME (STRING) -> DATETIME */ private FunctionResolver datetime() { - return define(BuiltinFunctionName.DATETIME.getName(), - impl(nullMissingHandling(DateTimeFunction::exprDateTime), - DATETIME, STRING, STRING), - impl(nullMissingHandling(DateTimeFunction::exprDateTimeNoTimezone), - DATETIME, STRING) - ); + return define( + BuiltinFunctionName.DATETIME.getName(), + impl(nullMissingHandling(DateTimeFunction::exprDateTime), DATETIME, STRING, STRING), + impl(nullMissingHandling(DateTimeFunction::exprDateTimeNoTimezone), DATETIME, STRING)); } private DefaultFunctionResolver date_add() { - return define(BuiltinFunctionName.DATE_ADD.getName(), + return define( + BuiltinFunctionName.DATE_ADD.getName(), (SerializableFunction>[]) get_date_add_date_sub_signatures(DateTimeFunction::exprAddDateInterval) .toArray(SerializableFunction[]::new)); } private DefaultFunctionResolver date_sub() { - return define(BuiltinFunctionName.DATE_SUB.getName(), + return define( + BuiltinFunctionName.DATE_SUB.getName(), (SerializableFunction>[]) get_date_add_date_sub_signatures(DateTimeFunction::exprSubDateInterval) .toArray(SerializableFunction[]::new)); } - /** - * DAY(STRING/DATE/DATETIME/TIMESTAMP). return the day of the month (1-31). - */ + /** DAY(STRING/DATE/DATETIME/TIMESTAMP). return the day of the month (1-31). */ private DefaultFunctionResolver day() { - return define(BuiltinFunctionName.DAY.getName(), + return define( + BuiltinFunctionName.DAY.getName(), impl(nullMissingHandling(DateTimeFunction::exprDayOfMonth), INTEGER, DATE), impl(nullMissingHandling(DateTimeFunction::exprDayOfMonth), INTEGER, DATETIME), impl(nullMissingHandling(DateTimeFunction::exprDayOfMonth), INTEGER, TIMESTAMP), - impl(nullMissingHandling(DateTimeFunction::exprDayOfMonth), INTEGER, STRING) - ); + impl(nullMissingHandling(DateTimeFunction::exprDayOfMonth), INTEGER, STRING)); } /** - * DAYNAME(STRING/DATE/DATETIME/TIMESTAMP). - * return the name of the weekday for date, including Monday, Tuesday, Wednesday, - * Thursday, Friday, Saturday and Sunday. + * DAYNAME(STRING/DATE/DATETIME/TIMESTAMP). return the name of the weekday for date, including + * Monday, Tuesday, Wednesday, Thursday, Friday, Saturday and Sunday. */ private DefaultFunctionResolver dayName() { - return define(BuiltinFunctionName.DAYNAME.getName(), + return define( + BuiltinFunctionName.DAYNAME.getName(), impl(nullMissingHandling(DateTimeFunction::exprDayName), STRING, DATE), impl(nullMissingHandling(DateTimeFunction::exprDayName), STRING, DATETIME), impl(nullMissingHandling(DateTimeFunction::exprDayName), STRING, TIMESTAMP), - impl(nullMissingHandling(DateTimeFunction::exprDayName), STRING, STRING) - ); + impl(nullMissingHandling(DateTimeFunction::exprDayName), STRING, STRING)); } - /** - * DAYOFMONTH(STRING/DATE/DATETIME/TIMESTAMP). return the day of the month (1-31). - */ + /** DAYOFMONTH(STRING/DATE/DATETIME/TIMESTAMP). return the day of the month (1-31). */ private DefaultFunctionResolver dayOfMonth(BuiltinFunctionName name) { - return define(name.getName(), - implWithProperties(nullMissingHandlingWithProperties( - (functionProperties, arg) -> DateTimeFunction.dayOfMonthToday( - functionProperties.getQueryStartClock())), INTEGER, TIME), + return define( + name.getName(), + implWithProperties( + nullMissingHandlingWithProperties( + (functionProperties, arg) -> + DateTimeFunction.dayOfMonthToday(functionProperties.getQueryStartClock())), + INTEGER, + TIME), impl(nullMissingHandling(DateTimeFunction::exprDayOfMonth), INTEGER, DATE), impl(nullMissingHandling(DateTimeFunction::exprDayOfMonth), INTEGER, DATETIME), impl(nullMissingHandling(DateTimeFunction::exprDayOfMonth), INTEGER, STRING), - impl(nullMissingHandling(DateTimeFunction::exprDayOfMonth), INTEGER, TIMESTAMP) - ); + impl(nullMissingHandling(DateTimeFunction::exprDayOfMonth), INTEGER, TIMESTAMP)); } /** - * DAYOFWEEK(STRING/DATE/DATETIME/TIME/TIMESTAMP). - * return the weekday index for date (1 = Sunday, 2 = Monday, ..., 7 = Saturday). + * DAYOFWEEK(STRING/DATE/DATETIME/TIME/TIMESTAMP). return the weekday index for date (1 = Sunday, + * 2 = Monday, ..., 7 = Saturday). */ private DefaultFunctionResolver dayOfWeek(FunctionName name) { - return define(name, - implWithProperties(nullMissingHandlingWithProperties( - (functionProperties, arg) -> DateTimeFunction.dayOfWeekToday( - functionProperties.getQueryStartClock())), INTEGER, TIME), + return define( + name, + implWithProperties( + nullMissingHandlingWithProperties( + (functionProperties, arg) -> + DateTimeFunction.dayOfWeekToday(functionProperties.getQueryStartClock())), + INTEGER, + TIME), impl(nullMissingHandling(DateTimeFunction::exprDayOfWeek), INTEGER, DATE), impl(nullMissingHandling(DateTimeFunction::exprDayOfWeek), INTEGER, DATETIME), impl(nullMissingHandling(DateTimeFunction::exprDayOfWeek), INTEGER, TIMESTAMP), - impl(nullMissingHandling(DateTimeFunction::exprDayOfWeek), INTEGER, STRING) - ); + impl(nullMissingHandling(DateTimeFunction::exprDayOfWeek), INTEGER, STRING)); } - /** - * DAYOFYEAR(STRING/DATE/DATETIME/TIMESTAMP). - * return the day of the year for date (1-366). - */ + /** DAYOFYEAR(STRING/DATE/DATETIME/TIMESTAMP). return the day of the year for date (1-366). */ private DefaultFunctionResolver dayOfYear(BuiltinFunctionName dayOfYear) { - return define(dayOfYear.getName(), - implWithProperties(nullMissingHandlingWithProperties((functionProperties, arg) - -> DateTimeFunction.dayOfYearToday( - functionProperties.getQueryStartClock())), INTEGER, TIME), + return define( + dayOfYear.getName(), + implWithProperties( + nullMissingHandlingWithProperties( + (functionProperties, arg) -> + DateTimeFunction.dayOfYearToday(functionProperties.getQueryStartClock())), + INTEGER, + TIME), impl(nullMissingHandling(DateTimeFunction::exprDayOfYear), INTEGER, DATE), impl(nullMissingHandling(DateTimeFunction::exprDayOfYear), INTEGER, DATETIME), impl(nullMissingHandling(DateTimeFunction::exprDayOfYear), INTEGER, TIMESTAMP), - impl(nullMissingHandling(DateTimeFunction::exprDayOfYear), INTEGER, STRING) - ); + impl(nullMissingHandling(DateTimeFunction::exprDayOfYear), INTEGER, STRING)); } private DefaultFunctionResolver extract() { - return define(BuiltinFunctionName.EXTRACT.getName(), - implWithProperties(nullMissingHandlingWithProperties(DateTimeFunction::exprExtractForTime), - LONG, STRING, TIME), + return define( + BuiltinFunctionName.EXTRACT.getName(), + implWithProperties( + nullMissingHandlingWithProperties(DateTimeFunction::exprExtractForTime), + LONG, + STRING, + TIME), impl(nullMissingHandling(DateTimeFunction::exprExtract), LONG, STRING, DATE), impl(nullMissingHandling(DateTimeFunction::exprExtract), LONG, STRING, DATETIME), impl(nullMissingHandling(DateTimeFunction::exprExtract), LONG, STRING, TIMESTAMP), - impl(nullMissingHandling(DateTimeFunction::exprExtract), LONG, STRING, STRING) - ); + impl(nullMissingHandling(DateTimeFunction::exprExtract), LONG, STRING, STRING)); } - /** - * FROM_DAYS(LONG). return the date value given the day number N. - */ + /** FROM_DAYS(LONG). return the date value given the day number N. */ private DefaultFunctionResolver from_days() { - return define(BuiltinFunctionName.FROM_DAYS.getName(), + return define( + BuiltinFunctionName.FROM_DAYS.getName(), impl(nullMissingHandling(DateTimeFunction::exprFromDays), DATE, LONG)); } private FunctionResolver from_unixtime() { - return define(BuiltinFunctionName.FROM_UNIXTIME.getName(), + return define( + BuiltinFunctionName.FROM_UNIXTIME.getName(), impl(nullMissingHandling(DateTimeFunction::exprFromUnixTime), DATETIME, DOUBLE), - impl(nullMissingHandling(DateTimeFunction::exprFromUnixTimeFormat), - STRING, DOUBLE, STRING)); + impl( + nullMissingHandling(DateTimeFunction::exprFromUnixTimeFormat), STRING, DOUBLE, STRING)); } private DefaultFunctionResolver get_format() { - return define(BuiltinFunctionName.GET_FORMAT.getName(), - impl(nullMissingHandling(DateTimeFunction::exprGetFormat), STRING, STRING, STRING) - ); + return define( + BuiltinFunctionName.GET_FORMAT.getName(), + impl(nullMissingHandling(DateTimeFunction::exprGetFormat), STRING, STRING, STRING)); } - /** - * HOUR(STRING/TIME/DATETIME/DATE/TIMESTAMP). return the hour value for time. - */ + /** HOUR(STRING/TIME/DATETIME/DATE/TIMESTAMP). return the hour value for time. */ private DefaultFunctionResolver hour(BuiltinFunctionName name) { - return define(name.getName(), + return define( + name.getName(), impl(nullMissingHandling(DateTimeFunction::exprHour), INTEGER, STRING), impl(nullMissingHandling(DateTimeFunction::exprHour), INTEGER, TIME), impl(nullMissingHandling(DateTimeFunction::exprHour), INTEGER, DATE), impl(nullMissingHandling(DateTimeFunction::exprHour), INTEGER, DATETIME), - impl(nullMissingHandling(DateTimeFunction::exprHour), INTEGER, TIMESTAMP) - ); + impl(nullMissingHandling(DateTimeFunction::exprHour), INTEGER, TIMESTAMP)); } - private DefaultFunctionResolver last_day() { - return define(BuiltinFunctionName.LAST_DAY.getName(), + private DefaultFunctionResolver last_day() { + return define( + BuiltinFunctionName.LAST_DAY.getName(), impl(nullMissingHandling(DateTimeFunction::exprLastDay), DATE, STRING), - implWithProperties(nullMissingHandlingWithProperties((functionProperties, arg) - -> DateTimeFunction.exprLastDayToday( - functionProperties.getQueryStartClock())), DATE, TIME), + implWithProperties( + nullMissingHandlingWithProperties( + (functionProperties, arg) -> + DateTimeFunction.exprLastDayToday(functionProperties.getQueryStartClock())), + DATE, + TIME), impl(nullMissingHandling(DateTimeFunction::exprLastDay), DATE, DATE), impl(nullMissingHandling(DateTimeFunction::exprLastDay), DATE, DATETIME), - impl(nullMissingHandling(DateTimeFunction::exprLastDay), DATE, TIMESTAMP) - ); + impl(nullMissingHandling(DateTimeFunction::exprLastDay), DATE, TIMESTAMP)); } private FunctionResolver makedate() { - return define(BuiltinFunctionName.MAKEDATE.getName(), + return define( + BuiltinFunctionName.MAKEDATE.getName(), impl(nullMissingHandling(DateTimeFunction::exprMakeDate), DATE, DOUBLE, DOUBLE)); } private FunctionResolver maketime() { - return define(BuiltinFunctionName.MAKETIME.getName(), + return define( + BuiltinFunctionName.MAKETIME.getName(), impl(nullMissingHandling(DateTimeFunction::exprMakeTime), TIME, DOUBLE, DOUBLE, DOUBLE)); } - /** - * MICROSECOND(STRING/TIME/DATETIME/TIMESTAMP). return the microsecond value for time. - */ + /** MICROSECOND(STRING/TIME/DATETIME/TIMESTAMP). return the microsecond value for time. */ private DefaultFunctionResolver microsecond() { - return define(BuiltinFunctionName.MICROSECOND.getName(), + return define( + BuiltinFunctionName.MICROSECOND.getName(), impl(nullMissingHandling(DateTimeFunction::exprMicrosecond), INTEGER, STRING), impl(nullMissingHandling(DateTimeFunction::exprMicrosecond), INTEGER, TIME), impl(nullMissingHandling(DateTimeFunction::exprMicrosecond), INTEGER, DATETIME), - impl(nullMissingHandling(DateTimeFunction::exprMicrosecond), INTEGER, TIMESTAMP) - ); + impl(nullMissingHandling(DateTimeFunction::exprMicrosecond), INTEGER, TIMESTAMP)); } - /** - * MINUTE(STRING/TIME/DATETIME/TIMESTAMP). return the minute value for time. - */ + /** MINUTE(STRING/TIME/DATETIME/TIMESTAMP). return the minute value for time. */ private DefaultFunctionResolver minute(BuiltinFunctionName name) { - return define(name.getName(), + return define( + name.getName(), impl(nullMissingHandling(DateTimeFunction::exprMinute), INTEGER, STRING), impl(nullMissingHandling(DateTimeFunction::exprMinute), INTEGER, TIME), impl(nullMissingHandling(DateTimeFunction::exprMinute), INTEGER, DATETIME), impl(nullMissingHandling(DateTimeFunction::exprMinute), INTEGER, DATE), - impl(nullMissingHandling(DateTimeFunction::exprMinute), INTEGER, TIMESTAMP) - ); + impl(nullMissingHandling(DateTimeFunction::exprMinute), INTEGER, TIMESTAMP)); } - /** - * MINUTE(STRING/TIME/DATETIME/TIMESTAMP). return the minute value for time. - */ + /** MINUTE(STRING/TIME/DATETIME/TIMESTAMP). return the minute value for time. */ private DefaultFunctionResolver minute_of_day() { - return define(BuiltinFunctionName.MINUTE_OF_DAY.getName(), + return define( + BuiltinFunctionName.MINUTE_OF_DAY.getName(), impl(nullMissingHandling(DateTimeFunction::exprMinuteOfDay), INTEGER, STRING), impl(nullMissingHandling(DateTimeFunction::exprMinuteOfDay), INTEGER, TIME), impl(nullMissingHandling(DateTimeFunction::exprMinuteOfDay), INTEGER, DATE), impl(nullMissingHandling(DateTimeFunction::exprMinuteOfDay), INTEGER, DATETIME), - impl(nullMissingHandling(DateTimeFunction::exprMinuteOfDay), INTEGER, TIMESTAMP) - ); + impl(nullMissingHandling(DateTimeFunction::exprMinuteOfDay), INTEGER, TIMESTAMP)); } - /** - * MONTH(STRING/DATE/DATETIME/TIMESTAMP). return the month for date (1-12). - */ + /** MONTH(STRING/DATE/DATETIME/TIMESTAMP). return the month for date (1-12). */ private DefaultFunctionResolver month(BuiltinFunctionName month) { - return define(month.getName(), - implWithProperties(nullMissingHandlingWithProperties((functionProperties, arg) - -> DateTimeFunction.monthOfYearToday( - functionProperties.getQueryStartClock())), INTEGER, TIME), + return define( + month.getName(), + implWithProperties( + nullMissingHandlingWithProperties( + (functionProperties, arg) -> + DateTimeFunction.monthOfYearToday(functionProperties.getQueryStartClock())), + INTEGER, + TIME), impl(nullMissingHandling(DateTimeFunction::exprMonth), INTEGER, DATE), impl(nullMissingHandling(DateTimeFunction::exprMonth), INTEGER, DATETIME), impl(nullMissingHandling(DateTimeFunction::exprMonth), INTEGER, TIMESTAMP), - impl(nullMissingHandling(DateTimeFunction::exprMonth), INTEGER, STRING) - ); + impl(nullMissingHandling(DateTimeFunction::exprMonth), INTEGER, STRING)); } - /** - * MONTHNAME(STRING/DATE/DATETIME/TIMESTAMP). return the full name of the month for date. - */ + /** MONTHNAME(STRING/DATE/DATETIME/TIMESTAMP). return the full name of the month for date. */ private DefaultFunctionResolver monthName() { - return define(BuiltinFunctionName.MONTHNAME.getName(), + return define( + BuiltinFunctionName.MONTHNAME.getName(), impl(nullMissingHandling(DateTimeFunction::exprMonthName), STRING, DATE), impl(nullMissingHandling(DateTimeFunction::exprMonthName), STRING, DATETIME), impl(nullMissingHandling(DateTimeFunction::exprMonthName), STRING, TIMESTAMP), - impl(nullMissingHandling(DateTimeFunction::exprMonthName), STRING, STRING) - ); + impl(nullMissingHandling(DateTimeFunction::exprMonthName), STRING, STRING)); } /** @@ -721,130 +791,161 @@ private DefaultFunctionResolver monthName() { * (INTEGER, INTEGER) -> INTEGER */ private DefaultFunctionResolver period_add() { - return define(BuiltinFunctionName.PERIOD_ADD.getName(), - impl(nullMissingHandling(DateTimeFunction::exprPeriodAdd), INTEGER, INTEGER, INTEGER) - ); + return define( + BuiltinFunctionName.PERIOD_ADD.getName(), + impl(nullMissingHandling(DateTimeFunction::exprPeriodAdd), INTEGER, INTEGER, INTEGER)); } /** - * Returns the number of months between periods P1 and P2. - * P1 and P2 should be in the format YYMM or YYYYMM. - * (INTEGER, INTEGER) -> INTEGER + * Returns the number of months between periods P1 and P2. P1 and P2 should be in the format YYMM + * or YYYYMM. (INTEGER, INTEGER) -> INTEGER */ private DefaultFunctionResolver period_diff() { - return define(BuiltinFunctionName.PERIOD_DIFF.getName(), - impl(nullMissingHandling(DateTimeFunction::exprPeriodDiff), INTEGER, INTEGER, INTEGER) - ); + return define( + BuiltinFunctionName.PERIOD_DIFF.getName(), + impl(nullMissingHandling(DateTimeFunction::exprPeriodDiff), INTEGER, INTEGER, INTEGER)); } - /** - * QUARTER(STRING/DATE/DATETIME/TIMESTAMP). return the month for date (1-4). - */ + /** QUARTER(STRING/DATE/DATETIME/TIMESTAMP). return the month for date (1-4). */ private DefaultFunctionResolver quarter() { - return define(BuiltinFunctionName.QUARTER.getName(), + return define( + BuiltinFunctionName.QUARTER.getName(), impl(nullMissingHandling(DateTimeFunction::exprQuarter), INTEGER, DATE), impl(nullMissingHandling(DateTimeFunction::exprQuarter), INTEGER, DATETIME), impl(nullMissingHandling(DateTimeFunction::exprQuarter), INTEGER, TIMESTAMP), - impl(nullMissingHandling(DateTimeFunction::exprQuarter), INTEGER, STRING) - ); + impl(nullMissingHandling(DateTimeFunction::exprQuarter), INTEGER, STRING)); } private DefaultFunctionResolver sec_to_time() { - return define(BuiltinFunctionName.SEC_TO_TIME.getName(), + return define( + BuiltinFunctionName.SEC_TO_TIME.getName(), impl((nullMissingHandling(DateTimeFunction::exprSecToTime)), TIME, INTEGER), impl((nullMissingHandling(DateTimeFunction::exprSecToTime)), TIME, LONG), impl((nullMissingHandling(DateTimeFunction::exprSecToTimeWithNanos)), TIME, DOUBLE), - impl((nullMissingHandling(DateTimeFunction::exprSecToTimeWithNanos)), TIME, FLOAT) - ); + impl((nullMissingHandling(DateTimeFunction::exprSecToTimeWithNanos)), TIME, FLOAT)); } - /** - * SECOND(STRING/TIME/DATETIME/TIMESTAMP). return the second value for time. - */ + /** SECOND(STRING/TIME/DATETIME/TIMESTAMP). return the second value for time. */ private DefaultFunctionResolver second(BuiltinFunctionName name) { - return define(name.getName(), + return define( + name.getName(), impl(nullMissingHandling(DateTimeFunction::exprSecond), INTEGER, STRING), impl(nullMissingHandling(DateTimeFunction::exprSecond), INTEGER, TIME), impl(nullMissingHandling(DateTimeFunction::exprSecond), INTEGER, DATE), impl(nullMissingHandling(DateTimeFunction::exprSecond), INTEGER, DATETIME), - impl(nullMissingHandling(DateTimeFunction::exprSecond), INTEGER, TIMESTAMP) - ); + impl(nullMissingHandling(DateTimeFunction::exprSecond), INTEGER, TIMESTAMP)); } private DefaultFunctionResolver subdate() { - return define(BuiltinFunctionName.SUBDATE.getName(), + return define( + BuiltinFunctionName.SUBDATE.getName(), (SerializableFunction>[]) (Stream.concat( - get_date_add_date_sub_signatures(DateTimeFunction::exprSubDateInterval), - get_adddate_subdate_signatures(DateTimeFunction::exprSubDateDays)) + get_date_add_date_sub_signatures(DateTimeFunction::exprSubDateInterval), + get_adddate_subdate_signatures(DateTimeFunction::exprSubDateDays)) .toArray(SerializableFunction[]::new))); } /** - * Subtracts expr2 from expr1 and returns the result. - * (TIME, TIME/DATE/DATETIME/TIMESTAMP) -> TIME - * (DATE/DATETIME/TIMESTAMP, TIME/DATE/DATETIME/TIMESTAMP) -> DATETIME - * TODO: MySQL has these signatures too - * (STRING, STRING/TIME) -> STRING // second arg - string with time only - * (x, STRING) -> NULL // second arg - string with timestamp - * (x, STRING/DATE) -> x // second arg - string with date only + * Subtracts expr2 from expr1 and returns the result. (TIME, TIME/DATE/DATETIME/TIMESTAMP) -> TIME + * (DATE/DATETIME/TIMESTAMP, TIME/DATE/DATETIME/TIMESTAMP) -> DATETIME TODO: MySQL has these + * signatures too (STRING, STRING/TIME) -> STRING // second arg - string with time only (x, + * STRING) -> NULL // second arg - string with timestamp (x, STRING/DATE) -> x // second arg - + * string with date only */ private DefaultFunctionResolver subtime() { - return define(BuiltinFunctionName.SUBTIME.getName(), - implWithProperties(nullMissingHandlingWithProperties(DateTimeFunction::exprSubTime), - TIME, TIME, TIME), - implWithProperties(nullMissingHandlingWithProperties(DateTimeFunction::exprSubTime), - TIME, TIME, DATE), - implWithProperties(nullMissingHandlingWithProperties(DateTimeFunction::exprSubTime), - TIME, TIME, DATETIME), - implWithProperties(nullMissingHandlingWithProperties(DateTimeFunction::exprSubTime), - TIME, TIME, TIMESTAMP), - implWithProperties(nullMissingHandlingWithProperties(DateTimeFunction::exprSubTime), - DATETIME, DATETIME, TIME), - implWithProperties(nullMissingHandlingWithProperties(DateTimeFunction::exprSubTime), - DATETIME, DATETIME, DATE), - implWithProperties(nullMissingHandlingWithProperties(DateTimeFunction::exprSubTime), - DATETIME, DATETIME, DATETIME), - implWithProperties(nullMissingHandlingWithProperties(DateTimeFunction::exprSubTime), - DATETIME, DATETIME, TIMESTAMP), - implWithProperties(nullMissingHandlingWithProperties(DateTimeFunction::exprSubTime), - DATETIME, DATE, TIME), - implWithProperties(nullMissingHandlingWithProperties(DateTimeFunction::exprSubTime), - DATETIME, DATE, DATE), - implWithProperties(nullMissingHandlingWithProperties(DateTimeFunction::exprSubTime), - DATETIME, DATE, DATETIME), - implWithProperties(nullMissingHandlingWithProperties(DateTimeFunction::exprSubTime), - DATETIME, DATE, TIMESTAMP), - implWithProperties(nullMissingHandlingWithProperties(DateTimeFunction::exprSubTime), - DATETIME, TIMESTAMP, TIME), - implWithProperties(nullMissingHandlingWithProperties(DateTimeFunction::exprSubTime), - DATETIME, TIMESTAMP, DATE), - implWithProperties(nullMissingHandlingWithProperties(DateTimeFunction::exprSubTime), - DATETIME, TIMESTAMP, DATETIME), - implWithProperties(nullMissingHandlingWithProperties(DateTimeFunction::exprSubTime), - DATETIME, TIMESTAMP, TIMESTAMP) - ); - } - - /** - * Extracts a date, time, or datetime from the given string. - * It accomplishes this using another string which specifies the input format. + return define( + BuiltinFunctionName.SUBTIME.getName(), + implWithProperties( + nullMissingHandlingWithProperties(DateTimeFunction::exprSubTime), TIME, TIME, TIME), + implWithProperties( + nullMissingHandlingWithProperties(DateTimeFunction::exprSubTime), TIME, TIME, DATE), + implWithProperties( + nullMissingHandlingWithProperties(DateTimeFunction::exprSubTime), TIME, TIME, DATETIME), + implWithProperties( + nullMissingHandlingWithProperties(DateTimeFunction::exprSubTime), + TIME, + TIME, + TIMESTAMP), + implWithProperties( + nullMissingHandlingWithProperties(DateTimeFunction::exprSubTime), + DATETIME, + DATETIME, + TIME), + implWithProperties( + nullMissingHandlingWithProperties(DateTimeFunction::exprSubTime), + DATETIME, + DATETIME, + DATE), + implWithProperties( + nullMissingHandlingWithProperties(DateTimeFunction::exprSubTime), + DATETIME, + DATETIME, + DATETIME), + implWithProperties( + nullMissingHandlingWithProperties(DateTimeFunction::exprSubTime), + DATETIME, + DATETIME, + TIMESTAMP), + implWithProperties( + nullMissingHandlingWithProperties(DateTimeFunction::exprSubTime), DATETIME, DATE, TIME), + implWithProperties( + nullMissingHandlingWithProperties(DateTimeFunction::exprSubTime), DATETIME, DATE, DATE), + implWithProperties( + nullMissingHandlingWithProperties(DateTimeFunction::exprSubTime), + DATETIME, + DATE, + DATETIME), + implWithProperties( + nullMissingHandlingWithProperties(DateTimeFunction::exprSubTime), + DATETIME, + DATE, + TIMESTAMP), + implWithProperties( + nullMissingHandlingWithProperties(DateTimeFunction::exprSubTime), + DATETIME, + TIMESTAMP, + TIME), + implWithProperties( + nullMissingHandlingWithProperties(DateTimeFunction::exprSubTime), + DATETIME, + TIMESTAMP, + DATE), + implWithProperties( + nullMissingHandlingWithProperties(DateTimeFunction::exprSubTime), + DATETIME, + TIMESTAMP, + DATETIME), + implWithProperties( + nullMissingHandlingWithProperties(DateTimeFunction::exprSubTime), + DATETIME, + TIMESTAMP, + TIMESTAMP)); + } + + /** + * Extracts a date, time, or datetime from the given string. It accomplishes this using another + * string which specifies the input format. */ private DefaultFunctionResolver str_to_date() { - return define(BuiltinFunctionName.STR_TO_DATE.getName(), + return define( + BuiltinFunctionName.STR_TO_DATE.getName(), implWithProperties( - nullMissingHandlingWithProperties((functionProperties, arg, format) - -> DateTimeFunction.exprStrToDate(functionProperties, arg, format)), - DATETIME, STRING, STRING)); + nullMissingHandlingWithProperties( + (functionProperties, arg, format) -> + DateTimeFunction.exprStrToDate(functionProperties, arg, format)), + DATETIME, + STRING, + STRING)); } /** - * Extracts the time part of a date and time value. - * Also to construct a time type. The supported signatures: - * STRING/DATE/DATETIME/TIME/TIMESTAMP -> TIME + * Extracts the time part of a date and time value. Also to construct a time type. The supported + * signatures: STRING/DATE/DATETIME/TIME/TIMESTAMP -> TIME */ private DefaultFunctionResolver time() { - return define(BuiltinFunctionName.TIME.getName(), + return define( + BuiltinFunctionName.TIME.getName(), impl(nullMissingHandling(DateTimeFunction::exprTime), TIME, STRING), impl(nullMissingHandling(DateTimeFunction::exprTime), TIME, DATE), impl(nullMissingHandling(DateTimeFunction::exprTime), TIME, DATETIME), @@ -853,18 +954,15 @@ private DefaultFunctionResolver time() { } /** - * Returns different between two times as a time. - * (TIME, TIME) -> TIME - * MySQL has these signatures too - * (DATE, DATE) -> TIME // result is > 24 hours - * (DATETIME, DATETIME) -> TIME // result is > 24 hours - * (TIMESTAMP, TIMESTAMP) -> TIME // result is > 24 hours - * (x, x) -> NULL // when args have different types - * (STRING, STRING) -> TIME // argument strings contain same types only - * (STRING, STRING) -> NULL // argument strings are different types + * Returns different between two times as a time. (TIME, TIME) -> TIME MySQL has these signatures + * too (DATE, DATE) -> TIME // result is > 24 hours (DATETIME, DATETIME) -> TIME // result is > 24 + * hours (TIMESTAMP, TIMESTAMP) -> TIME // result is > 24 hours (x, x) -> NULL // when args have + * different types (STRING, STRING) -> TIME // argument strings contain same types only (STRING, + * STRING) -> NULL // argument strings are different types */ private DefaultFunctionResolver timediff() { - return define(BuiltinFunctionName.TIMEDIFF.getName(), + return define( + BuiltinFunctionName.TIMEDIFF.getName(), impl(nullMissingHandling(DateTimeFunction::exprTimeDiff), TIME, TIME, TIME)); } @@ -872,90 +970,120 @@ private DefaultFunctionResolver timediff() { * TIME_TO_SEC(STRING/TIME/DATETIME/TIMESTAMP). return the time argument, converted to seconds. */ private DefaultFunctionResolver time_to_sec() { - return define(BuiltinFunctionName.TIME_TO_SEC.getName(), + return define( + BuiltinFunctionName.TIME_TO_SEC.getName(), impl(nullMissingHandling(DateTimeFunction::exprTimeToSec), LONG, STRING), impl(nullMissingHandling(DateTimeFunction::exprTimeToSec), LONG, TIME), impl(nullMissingHandling(DateTimeFunction::exprTimeToSec), LONG, TIMESTAMP), - impl(nullMissingHandling(DateTimeFunction::exprTimeToSec), LONG, DATETIME) - ); + impl(nullMissingHandling(DateTimeFunction::exprTimeToSec), LONG, DATETIME)); } /** - * Extracts the timestamp of a date and time value. - * Input strings may contain a timestamp only in format 'yyyy-MM-dd HH:mm:ss[.SSSSSSSSS]' - * STRING/DATE/TIME/DATETIME/TIMESTAMP -> TIMESTAMP - * STRING/DATE/TIME/DATETIME/TIMESTAMP, STRING/DATE/TIME/DATETIME/TIMESTAMP -> TIMESTAMP - * All types are converted to TIMESTAMP actually before the function call - it is responsibility - * of the automatic cast mechanism defined in `ExprCoreType` and performed by `TypeCastOperator`. + * Extracts the timestamp of a date and time value. Input strings may contain a timestamp only in + * format 'yyyy-MM-dd HH:mm:ss[.SSSSSSSSS]' STRING/DATE/TIME/DATETIME/TIMESTAMP -> TIMESTAMP + * STRING/DATE/TIME/DATETIME/TIMESTAMP, STRING/DATE/TIME/DATETIME/TIMESTAMP -> TIMESTAMP All types + * are converted to TIMESTAMP actually before the function call - it is responsibility of the + * automatic cast mechanism defined in `ExprCoreType` and performed by `TypeCastOperator`. */ private DefaultFunctionResolver timestamp() { - return define(BuiltinFunctionName.TIMESTAMP.getName(), + return define( + BuiltinFunctionName.TIMESTAMP.getName(), impl(nullMissingHandling(v -> v), TIMESTAMP, TIMESTAMP), // We can use FunctionProperties.None, because it is not used. It is required to convert // TIME to other datetime types, but arguments there are already converted. - impl(nullMissingHandling((v1, v2) -> exprAddTime(FunctionProperties.None, v1, v2)), - TIMESTAMP, TIMESTAMP, TIMESTAMP)); + impl( + nullMissingHandling((v1, v2) -> exprAddTime(FunctionProperties.None, v1, v2)), + TIMESTAMP, + TIMESTAMP, + TIMESTAMP)); } /** - * Adds an interval of time to the provided DATE/DATETIME/TIME/TIMESTAMP/STRING argument. - * The interval of time added is determined by the given first and second arguments. - * The first argument is an interval type, and must be one of the tokens below... - * [MICROSECOND, SECOND, MINUTE, HOUR, DAY, WEEK, MONTH, QUARTER, YEAR] - * The second argument is the amount of the interval type to be added. - * The third argument is the DATE/DATETIME/TIME/TIMESTAMP/STRING to add to. + * Adds an interval of time to the provided DATE/DATETIME/TIME/TIMESTAMP/STRING argument. The + * interval of time added is determined by the given first and second arguments. The first + * argument is an interval type, and must be one of the tokens below... [MICROSECOND, SECOND, + * MINUTE, HOUR, DAY, WEEK, MONTH, QUARTER, YEAR] The second argument is the amount of the + * interval type to be added. The third argument is the DATE/DATETIME/TIME/TIMESTAMP/STRING to add + * to. + * * @return The DATETIME representing the summed DATE/DATETIME/TIME/TIMESTAMP and interval. */ private DefaultFunctionResolver timestampadd() { - return define(BuiltinFunctionName.TIMESTAMPADD.getName(), - impl(nullMissingHandling(DateTimeFunction::exprTimestampAdd), - DATETIME, STRING, INTEGER, DATETIME), - impl(nullMissingHandling(DateTimeFunction::exprTimestampAdd), - DATETIME, STRING, INTEGER, TIMESTAMP), + return define( + BuiltinFunctionName.TIMESTAMPADD.getName(), + impl( + nullMissingHandling(DateTimeFunction::exprTimestampAdd), + DATETIME, + STRING, + INTEGER, + DATETIME), + impl( + nullMissingHandling(DateTimeFunction::exprTimestampAdd), + DATETIME, + STRING, + INTEGER, + TIMESTAMP), implWithProperties( nullMissingHandlingWithProperties( - (functionProperties, part, amount, time) -> exprTimestampAddForTimeType( - functionProperties.getQueryStartClock(), - part, - amount, - time)), - DATETIME, STRING, INTEGER, TIME)); + (functionProperties, part, amount, time) -> + exprTimestampAddForTimeType( + functionProperties.getQueryStartClock(), part, amount, time)), + DATETIME, + STRING, + INTEGER, + TIME)); } /** - * Finds the difference between provided DATE/DATETIME/TIME/TIMESTAMP/STRING arguments. - * The first argument is an interval type, and must be one of the tokens below... - * [MICROSECOND, SECOND, MINUTE, HOUR, DAY, WEEK, MONTH, QUARTER, YEAR] - * The second argument the DATE/DATETIME/TIME/TIMESTAMP/STRING representing the start time. - * The third argument is the DATE/DATETIME/TIME/TIMESTAMP/STRING representing the end time. + * Finds the difference between provided DATE/DATETIME/TIME/TIMESTAMP/STRING arguments. The first + * argument is an interval type, and must be one of the tokens below... [MICROSECOND, SECOND, + * MINUTE, HOUR, DAY, WEEK, MONTH, QUARTER, YEAR] The second argument the + * DATE/DATETIME/TIME/TIMESTAMP/STRING representing the start time. The third argument is the + * DATE/DATETIME/TIME/TIMESTAMP/STRING representing the end time. + * * @return A LONG representing the difference between arguments, using the given interval type. */ private DefaultFunctionResolver timestampdiff() { - return define(BuiltinFunctionName.TIMESTAMPDIFF.getName(), - impl(nullMissingHandling(DateTimeFunction::exprTimestampDiff), - DATETIME, STRING, DATETIME, DATETIME), - impl(nullMissingHandling(DateTimeFunction::exprTimestampDiff), - DATETIME, STRING, DATETIME, TIMESTAMP), - impl(nullMissingHandling(DateTimeFunction::exprTimestampDiff), - DATETIME, STRING, TIMESTAMP, DATETIME), - impl(nullMissingHandling(DateTimeFunction::exprTimestampDiff), - DATETIME, STRING, TIMESTAMP, TIMESTAMP), + return define( + BuiltinFunctionName.TIMESTAMPDIFF.getName(), + impl( + nullMissingHandling(DateTimeFunction::exprTimestampDiff), + DATETIME, + STRING, + DATETIME, + DATETIME), + impl( + nullMissingHandling(DateTimeFunction::exprTimestampDiff), + DATETIME, + STRING, + DATETIME, + TIMESTAMP), + impl( + nullMissingHandling(DateTimeFunction::exprTimestampDiff), + DATETIME, + STRING, + TIMESTAMP, + DATETIME), + impl( + nullMissingHandling(DateTimeFunction::exprTimestampDiff), + DATETIME, + STRING, + TIMESTAMP, + TIMESTAMP), implWithProperties( nullMissingHandlingWithProperties( - (functionProperties, part, startTime, endTime) -> exprTimestampDiffForTimeType( - functionProperties, - part, - startTime, - endTime)), - DATETIME, STRING, TIME, TIME) - ); + (functionProperties, part, startTime, endTime) -> + exprTimestampDiffForTimeType(functionProperties, part, startTime, endTime)), + DATETIME, + STRING, + TIME, + TIME)); } - /** - * TO_DAYS(STRING/DATE/DATETIME/TIMESTAMP). return the day number of the given date. - */ + /** TO_DAYS(STRING/DATE/DATETIME/TIMESTAMP). return the day number of the given date. */ private DefaultFunctionResolver to_days() { - return define(BuiltinFunctionName.TO_DAYS.getName(), + return define( + BuiltinFunctionName.TO_DAYS.getName(), impl(nullMissingHandling(DateTimeFunction::exprToDays), LONG, STRING), impl(nullMissingHandling(DateTimeFunction::exprToDays), LONG, TIMESTAMP), impl(nullMissingHandling(DateTimeFunction::exprToDays), LONG, DATE), @@ -963,156 +1091,162 @@ private DefaultFunctionResolver to_days() { } /** - * TO_SECONDS(TIMESTAMP/LONG). return the seconds number of the given date. - * Arguments of type STRING/TIMESTAMP/LONG are also accepted. - * STRING/TIMESTAMP/LONG arguments are automatically cast to TIMESTAMP. + * TO_SECONDS(TIMESTAMP/LONG). return the seconds number of the given date. Arguments of type + * STRING/TIMESTAMP/LONG are also accepted. STRING/TIMESTAMP/LONG arguments are automatically cast + * to TIMESTAMP. */ private DefaultFunctionResolver to_seconds() { - return define(BuiltinFunctionName.TO_SECONDS.getName(), + return define( + BuiltinFunctionName.TO_SECONDS.getName(), impl(nullMissingHandling(DateTimeFunction::exprToSeconds), LONG, TIMESTAMP), impl(nullMissingHandling(DateTimeFunction::exprToSecondsForIntType), LONG, LONG)); } private FunctionResolver unix_timestamp() { - return define(BuiltinFunctionName.UNIX_TIMESTAMP.getName(), - implWithProperties(functionProperties - -> DateTimeFunction.unixTimeStamp(functionProperties.getQueryStartClock()), LONG), + return define( + BuiltinFunctionName.UNIX_TIMESTAMP.getName(), + implWithProperties( + functionProperties -> + DateTimeFunction.unixTimeStamp(functionProperties.getQueryStartClock()), + LONG), impl(nullMissingHandling(DateTimeFunction::unixTimeStampOf), DOUBLE, DATE), impl(nullMissingHandling(DateTimeFunction::unixTimeStampOf), DOUBLE, DATETIME), impl(nullMissingHandling(DateTimeFunction::unixTimeStampOf), DOUBLE, TIMESTAMP), - impl(nullMissingHandling(DateTimeFunction::unixTimeStampOf), DOUBLE, DOUBLE) - ); + impl(nullMissingHandling(DateTimeFunction::unixTimeStampOf), DOUBLE, DOUBLE)); } - /** - * UTC_DATE(). return the current UTC Date in format yyyy-MM-dd - */ + /** UTC_DATE(). return the current UTC Date in format yyyy-MM-dd */ private DefaultFunctionResolver utc_date() { - return define(BuiltinFunctionName.UTC_DATE.getName(), - implWithProperties(functionProperties - -> exprUtcDate(functionProperties), DATE)); + return define( + BuiltinFunctionName.UTC_DATE.getName(), + implWithProperties(functionProperties -> exprUtcDate(functionProperties), DATE)); } - /** - * UTC_TIME(). return the current UTC Time in format HH:mm:ss - */ + /** UTC_TIME(). return the current UTC Time in format HH:mm:ss */ private DefaultFunctionResolver utc_time() { - return define(BuiltinFunctionName.UTC_TIME.getName(), - implWithProperties(functionProperties - -> exprUtcTime(functionProperties), TIME)); + return define( + BuiltinFunctionName.UTC_TIME.getName(), + implWithProperties(functionProperties -> exprUtcTime(functionProperties), TIME)); } - /** - * UTC_TIMESTAMP(). return the current UTC TimeStamp in format yyyy-MM-dd HH:mm:ss - */ + /** UTC_TIMESTAMP(). return the current UTC TimeStamp in format yyyy-MM-dd HH:mm:ss */ private DefaultFunctionResolver utc_timestamp() { - return define(BuiltinFunctionName.UTC_TIMESTAMP.getName(), - implWithProperties(functionProperties - -> exprUtcTimeStamp(functionProperties), DATETIME)); + return define( + BuiltinFunctionName.UTC_TIMESTAMP.getName(), + implWithProperties(functionProperties -> exprUtcTimeStamp(functionProperties), DATETIME)); } - /** - * WEEK(DATE[,mode]). return the week number for date. - */ + /** WEEK(DATE[,mode]). return the week number for date. */ private DefaultFunctionResolver week(BuiltinFunctionName week) { - return define(week.getName(), - implWithProperties(nullMissingHandlingWithProperties((functionProperties, arg) - -> DateTimeFunction.weekOfYearToday( - DEFAULT_WEEK_OF_YEAR_MODE, - functionProperties.getQueryStartClock())), INTEGER, TIME), + return define( + week.getName(), + implWithProperties( + nullMissingHandlingWithProperties( + (functionProperties, arg) -> + DateTimeFunction.weekOfYearToday( + DEFAULT_WEEK_OF_YEAR_MODE, functionProperties.getQueryStartClock())), + INTEGER, + TIME), impl(nullMissingHandling(DateTimeFunction::exprWeekWithoutMode), INTEGER, DATE), impl(nullMissingHandling(DateTimeFunction::exprWeekWithoutMode), INTEGER, DATETIME), impl(nullMissingHandling(DateTimeFunction::exprWeekWithoutMode), INTEGER, TIMESTAMP), impl(nullMissingHandling(DateTimeFunction::exprWeekWithoutMode), INTEGER, STRING), - implWithProperties(nullMissingHandlingWithProperties((functionProperties, time, modeArg) - -> DateTimeFunction.weekOfYearToday( - modeArg, - functionProperties.getQueryStartClock())), INTEGER, TIME, INTEGER), + implWithProperties( + nullMissingHandlingWithProperties( + (functionProperties, time, modeArg) -> + DateTimeFunction.weekOfYearToday( + modeArg, functionProperties.getQueryStartClock())), + INTEGER, + TIME, + INTEGER), impl(nullMissingHandling(DateTimeFunction::exprWeek), INTEGER, DATE, INTEGER), impl(nullMissingHandling(DateTimeFunction::exprWeek), INTEGER, DATETIME, INTEGER), impl(nullMissingHandling(DateTimeFunction::exprWeek), INTEGER, TIMESTAMP, INTEGER), - impl(nullMissingHandling(DateTimeFunction::exprWeek), INTEGER, STRING, INTEGER) - ); + impl(nullMissingHandling(DateTimeFunction::exprWeek), INTEGER, STRING, INTEGER)); } private DefaultFunctionResolver weekday() { - return define(BuiltinFunctionName.WEEKDAY.getName(), - implWithProperties(nullMissingHandlingWithProperties( - (functionProperties, arg) -> new ExprIntegerValue( - formatNow(functionProperties.getQueryStartClock()).getDayOfWeek().getValue() - 1)), - INTEGER, TIME), + return define( + BuiltinFunctionName.WEEKDAY.getName(), + implWithProperties( + nullMissingHandlingWithProperties( + (functionProperties, arg) -> + new ExprIntegerValue( + formatNow(functionProperties.getQueryStartClock()).getDayOfWeek().getValue() + - 1)), + INTEGER, + TIME), impl(nullMissingHandling(DateTimeFunction::exprWeekday), INTEGER, DATE), impl(nullMissingHandling(DateTimeFunction::exprWeekday), INTEGER, DATETIME), impl(nullMissingHandling(DateTimeFunction::exprWeekday), INTEGER, TIMESTAMP), - impl(nullMissingHandling(DateTimeFunction::exprWeekday), INTEGER, STRING) - ); + impl(nullMissingHandling(DateTimeFunction::exprWeekday), INTEGER, STRING)); } - /** - * YEAR(STRING/DATE/DATETIME/TIMESTAMP). return the year for date (1000-9999). - */ + /** YEAR(STRING/DATE/DATETIME/TIMESTAMP). return the year for date (1000-9999). */ private DefaultFunctionResolver year() { - return define(BuiltinFunctionName.YEAR.getName(), + return define( + BuiltinFunctionName.YEAR.getName(), impl(nullMissingHandling(DateTimeFunction::exprYear), INTEGER, DATE), impl(nullMissingHandling(DateTimeFunction::exprYear), INTEGER, DATETIME), impl(nullMissingHandling(DateTimeFunction::exprYear), INTEGER, TIMESTAMP), - impl(nullMissingHandling(DateTimeFunction::exprYear), INTEGER, STRING) - ); + impl(nullMissingHandling(DateTimeFunction::exprYear), INTEGER, STRING)); } - /** - * YEARWEEK(DATE[,mode]). return the week number for date. - */ + /** YEARWEEK(DATE[,mode]). return the week number for date. */ private DefaultFunctionResolver yearweek() { - return define(BuiltinFunctionName.YEARWEEK.getName(), - implWithProperties(nullMissingHandlingWithProperties((functionProperties, arg) - -> yearweekToday( - DEFAULT_WEEK_OF_YEAR_MODE, - functionProperties.getQueryStartClock())), INTEGER, TIME), + return define( + BuiltinFunctionName.YEARWEEK.getName(), + implWithProperties( + nullMissingHandlingWithProperties( + (functionProperties, arg) -> + yearweekToday( + DEFAULT_WEEK_OF_YEAR_MODE, functionProperties.getQueryStartClock())), + INTEGER, + TIME), impl(nullMissingHandling(DateTimeFunction::exprYearweekWithoutMode), INTEGER, DATE), impl(nullMissingHandling(DateTimeFunction::exprYearweekWithoutMode), INTEGER, DATETIME), impl(nullMissingHandling(DateTimeFunction::exprYearweekWithoutMode), INTEGER, TIMESTAMP), impl(nullMissingHandling(DateTimeFunction::exprYearweekWithoutMode), INTEGER, STRING), - implWithProperties(nullMissingHandlingWithProperties((functionProperties, time, modeArg) - -> yearweekToday( - modeArg, - functionProperties.getQueryStartClock())), INTEGER, TIME, INTEGER), + implWithProperties( + nullMissingHandlingWithProperties( + (functionProperties, time, modeArg) -> + yearweekToday(modeArg, functionProperties.getQueryStartClock())), + INTEGER, + TIME, + INTEGER), impl(nullMissingHandling(DateTimeFunction::exprYearweek), INTEGER, DATE, INTEGER), impl(nullMissingHandling(DateTimeFunction::exprYearweek), INTEGER, DATETIME, INTEGER), impl(nullMissingHandling(DateTimeFunction::exprYearweek), INTEGER, TIMESTAMP, INTEGER), - impl(nullMissingHandling(DateTimeFunction::exprYearweek), INTEGER, STRING, INTEGER) - ); + impl(nullMissingHandling(DateTimeFunction::exprYearweek), INTEGER, STRING, INTEGER)); } /** - * Formats date according to format specifier. First argument is date, second is format. - * Detailed supported signatures: - * (STRING, STRING) -> STRING - * (DATE, STRING) -> STRING - * (DATETIME, STRING) -> STRING - * (TIME, STRING) -> STRING - * (TIMESTAMP, STRING) -> STRING + * Formats date according to format specifier. First argument is date, second is format. Detailed + * supported signatures: (STRING, STRING) -> STRING (DATE, STRING) -> STRING (DATETIME, STRING) -> + * STRING (TIME, STRING) -> STRING (TIMESTAMP, STRING) -> STRING */ private DefaultFunctionResolver date_format() { - return define(BuiltinFunctionName.DATE_FORMAT.getName(), - impl(nullMissingHandling(DateTimeFormatterUtil::getFormattedDate), - STRING, STRING, STRING), - impl(nullMissingHandling(DateTimeFormatterUtil::getFormattedDate), - STRING, DATE, STRING), - impl(nullMissingHandling(DateTimeFormatterUtil::getFormattedDate), - STRING, DATETIME, STRING), + return define( + BuiltinFunctionName.DATE_FORMAT.getName(), + impl(nullMissingHandling(DateTimeFormatterUtil::getFormattedDate), STRING, STRING, STRING), + impl(nullMissingHandling(DateTimeFormatterUtil::getFormattedDate), STRING, DATE, STRING), + impl( + nullMissingHandling(DateTimeFormatterUtil::getFormattedDate), STRING, DATETIME, STRING), implWithProperties( nullMissingHandlingWithProperties( - (functionProperties, time, formatString) - -> DateTimeFormatterUtil.getFormattedDateOfToday( + (functionProperties, time, formatString) -> + DateTimeFormatterUtil.getFormattedDateOfToday( formatString, time, functionProperties.getQueryStartClock())), - STRING, TIME, STRING), - impl(nullMissingHandling(DateTimeFormatterUtil::getFormattedDate), - STRING, TIMESTAMP, STRING) - ); + STRING, + TIME, + STRING), + impl( + nullMissingHandling(DateTimeFormatterUtil::getFormattedDate), + STRING, + TIMESTAMP, + STRING)); } - private ExprValue dayOfMonthToday(Clock clock) { return new ExprIntegerValue(LocalDateTime.now(clock).getDayOfMonth()); } @@ -1144,8 +1278,8 @@ private ExprValue dayOfWeekToday(Clock clock) { * @param interval ExprValue of Interval type, the temporal amount to add. * @return Datetime resulted from `interval` added to `datetime`. */ - private ExprValue exprAddDateInterval(FunctionProperties functionProperties, - ExprValue datetime, ExprValue interval) { + private ExprValue exprAddDateInterval( + FunctionProperties functionProperties, ExprValue datetime, ExprValue interval) { return exprDateApplyInterval(functionProperties, datetime, interval.intervalValue(), true); } @@ -1158,36 +1292,33 @@ private ExprValue exprAddDateInterval(FunctionProperties functionProperties, * @param isAdd A flag: true to isAdd, false to subtract. * @return Datetime calculated. */ - private ExprValue exprDateApplyInterval(FunctionProperties functionProperties, - ExprValue datetime, - TemporalAmount interval, - Boolean isAdd) { + private ExprValue exprDateApplyInterval( + FunctionProperties functionProperties, + ExprValue datetime, + TemporalAmount interval, + Boolean isAdd) { var dt = extractDateTime(datetime, functionProperties); return new ExprDatetimeValue(isAdd ? dt.plus(interval) : dt.minus(interval)); } - + /** - * Formats date according to format specifier. First argument is time, second is format. - * Detailed supported signatures: - * (STRING, STRING) -> STRING - * (DATE, STRING) -> STRING - * (DATETIME, STRING) -> STRING - * (TIME, STRING) -> STRING - * (TIMESTAMP, STRING) -> STRING + * Formats date according to format specifier. First argument is time, second is format. Detailed + * supported signatures: (STRING, STRING) -> STRING (DATE, STRING) -> STRING (DATETIME, STRING) -> + * STRING (TIME, STRING) -> STRING (TIMESTAMP, STRING) -> STRING */ private DefaultFunctionResolver time_format() { - return define(BuiltinFunctionName.TIME_FORMAT.getName(), - impl(nullMissingHandling(DateTimeFormatterUtil::getFormattedTime), - STRING, STRING, STRING), - impl(nullMissingHandling(DateTimeFormatterUtil::getFormattedTime), - STRING, DATE, STRING), - impl(nullMissingHandling(DateTimeFormatterUtil::getFormattedTime), - STRING, DATETIME, STRING), - impl(nullMissingHandling(DateTimeFormatterUtil::getFormattedTime), - STRING, TIME, STRING), - impl(nullMissingHandling(DateTimeFormatterUtil::getFormattedTime), - STRING, TIMESTAMP, STRING) - ); + return define( + BuiltinFunctionName.TIME_FORMAT.getName(), + impl(nullMissingHandling(DateTimeFormatterUtil::getFormattedTime), STRING, STRING, STRING), + impl(nullMissingHandling(DateTimeFormatterUtil::getFormattedTime), STRING, DATE, STRING), + impl( + nullMissingHandling(DateTimeFormatterUtil::getFormattedTime), STRING, DATETIME, STRING), + impl(nullMissingHandling(DateTimeFormatterUtil::getFormattedTime), STRING, TIME, STRING), + impl( + nullMissingHandling(DateTimeFormatterUtil::getFormattedTime), + STRING, + TIMESTAMP, + STRING)); } /** @@ -1198,8 +1329,8 @@ private DefaultFunctionResolver time_format() { * @param days ExprValue of Long type, representing the number of days to add. * @return Date/Datetime resulted from days added to `datetime`. */ - private ExprValue exprAddDateDays(FunctionProperties functionProperties, - ExprValue datetime, ExprValue days) { + private ExprValue exprAddDateDays( + FunctionProperties functionProperties, ExprValue datetime, ExprValue days) { return exprDateApplyDays(functionProperties, datetime, days.longValue(), true); } @@ -1212,11 +1343,11 @@ private ExprValue exprAddDateDays(FunctionProperties functionProperties, * @param isAdd A flag: true to add, false to subtract. * @return Datetime calculated. */ - private ExprValue exprDateApplyDays(FunctionProperties functionProperties, - ExprValue datetime, Long days, Boolean isAdd) { + private ExprValue exprDateApplyDays( + FunctionProperties functionProperties, ExprValue datetime, Long days, Boolean isAdd) { if (datetime.type() == DATE) { - return new ExprDateValue(isAdd ? datetime.dateValue().plusDays(days) - : datetime.dateValue().minusDays(days)); + return new ExprDateValue( + isAdd ? datetime.dateValue().plusDays(days) : datetime.dateValue().minusDays(days)); } var dt = extractDateTime(datetime, functionProperties); return new ExprDatetimeValue(isAdd ? dt.plusDays(days) : dt.minusDays(days)); @@ -1231,12 +1362,16 @@ private ExprValue exprDateApplyDays(FunctionProperties functionProperties, * @param isAdd A flag: true to add, false to subtract. * @return A value calculated. */ - private ExprValue exprApplyTime(FunctionProperties functionProperties, - ExprValue temporal, ExprValue temporalDelta, Boolean isAdd) { + private ExprValue exprApplyTime( + FunctionProperties functionProperties, + ExprValue temporal, + ExprValue temporalDelta, + Boolean isAdd) { var interval = Duration.between(LocalTime.MIN, temporalDelta.timeValue()); - var result = isAdd - ? extractDateTime(temporal, functionProperties).plus(interval) - : extractDateTime(temporal, functionProperties).minus(interval); + var result = + isAdd + ? extractDateTime(temporal, functionProperties).plus(interval) + : extractDateTime(temporal, functionProperties).minus(interval); return temporal.type() == TIME ? new ExprTimeValue(result.toLocalTime()) : new ExprDatetimeValue(result); @@ -1250,18 +1385,18 @@ private ExprValue exprApplyTime(FunctionProperties functionProperties, * @param temporalDelta A Date/Time/Datetime/Timestamp object to add time from. * @return A value calculated. */ - private ExprValue exprAddTime(FunctionProperties functionProperties, - ExprValue temporal, ExprValue temporalDelta) { + private ExprValue exprAddTime( + FunctionProperties functionProperties, ExprValue temporal, ExprValue temporalDelta) { return exprApplyTime(functionProperties, temporal, temporalDelta, true); } /** - * CONVERT_TZ function implementation for ExprValue. - * Returns null for time zones outside of +13:00 and -12:00. + * CONVERT_TZ function implementation for ExprValue. Returns null for time zones outside of +13:00 + * and -12:00. * * @param startingDateTime ExprValue of DateTime that is being converted from - * @param fromTz ExprValue of time zone, representing the time to convert from. - * @param toTz ExprValue of time zone, representing the time to convert to. + * @param fromTz ExprValue of time zone, representing the time to convert from. + * @param toTz ExprValue of time zone, representing the time to convert to. * @return DateTime that has been converted to the to_tz timezone. */ private ExprValue exprConvertTZ(ExprValue startingDateTime, ExprValue fromTz, ExprValue toTz) { @@ -1278,8 +1413,7 @@ private ExprValue exprConvertTZ(ExprValue startingDateTime, ExprValue fromTz, Ex || !DateTimeUtils.isValidMySqlTimeZoneId(convertedToTz)) { return ExprNullValue.of(); } - ZonedDateTime zonedDateTime = - startingDateTime.datetimeValue().atZone(convertedFromTz); + ZonedDateTime zonedDateTime = startingDateTime.datetimeValue().atZone(convertedFromTz); return new ExprDatetimeValue( zonedDateTime.withZoneSameInstant(convertedToTz).toLocalDateTime()); @@ -1305,19 +1439,19 @@ private ExprValue exprDate(ExprValue exprValue) { } /** - * Calculate the value in days from one date to the other. - * Only the date parts of the values are used in the calculation. + * Calculate the value in days from one date to the other. Only the date parts of the values are + * used in the calculation. * * @param first The first value. * @param second The second value. * @return The diff. */ - private ExprValue exprDateDiff(FunctionProperties functionProperties, - ExprValue first, ExprValue second) { + private ExprValue exprDateDiff( + FunctionProperties functionProperties, ExprValue first, ExprValue second) { // java inverses the value, so we have to swap 1 and 2 - return new ExprLongValue(DAYS.between( - extractDate(second, functionProperties), - extractDate(first, functionProperties))); + return new ExprLongValue( + DAYS.between( + extractDate(second, functionProperties), extractDate(first, functionProperties))); } /** @@ -1357,10 +1491,7 @@ private ExprValue exprDateTime(ExprValue dateTime, ExprValue timeZone) { ldt = new ExprDatetimeValue(dateTime.stringValue()); toTz = defaultTimeZone; } - convertTZResult = exprConvertTZ( - ldt, - new ExprStringValue(toTz), - timeZone); + convertTZResult = exprConvertTZ(ldt, new ExprStringValue(toTz), timeZone); return convertTZResult; } @@ -1426,8 +1557,8 @@ private ExprValue exprDayOfYear(ExprValue date) { public ExprLongValue formatExtractFunction(ExprValue part, ExprValue datetime) { String partName = part.stringValue().toUpperCase(); LocalDateTime arg = datetime.datetimeValue(); - String text = arg.format(DateTimeFormatter.ofPattern( - extract_formats.get(partName), Locale.ENGLISH)); + String text = + arg.format(DateTimeFormatter.ofPattern(extract_formats.get(partName), Locale.ENGLISH)); return new ExprLongValue(Long.parseLong(text)); } @@ -1450,12 +1581,10 @@ private ExprValue exprExtract(ExprValue part, ExprValue datetime) { * @param time The time to be formatted. * @return A LONG */ - private ExprValue exprExtractForTime(FunctionProperties functionProperties, - ExprValue part, - ExprValue time) { + private ExprValue exprExtractForTime( + FunctionProperties functionProperties, ExprValue part, ExprValue time) { return formatExtractFunction( - part, - new ExprDatetimeValue(extractDateTime(time, functionProperties))); + part, new ExprDatetimeValue(extractDateTime(time, functionProperties))); } /** @@ -1484,9 +1613,8 @@ private ExprValue exprFromUnixTime(ExprValue time) { private LocalDateTime exprFromUnixTimeImpl(ExprValue time) { return LocalDateTime.ofInstant( - Instant.ofEpochSecond((long)Math.floor(time.doubleValue())), - UTC_ZONE_ID) - .withNano((int)((time.doubleValue() % 1) * 1E9)); + Instant.ofEpochSecond((long) Math.floor(time.doubleValue())), UTC_ZONE_ID) + .withNano((int) ((time.doubleValue() % 1) * 1E9)); } private ExprValue exprFromUnixTimeFormat(ExprValue time, ExprValue format) { @@ -1506,9 +1634,8 @@ private ExprValue exprFromUnixTimeFormat(ExprValue time, ExprValue format) { */ private ExprValue exprGetFormat(ExprValue type, ExprValue format) { if (formats.contains(type.stringValue().toLowerCase(), format.stringValue().toLowerCase())) { - return new ExprStringValue(formats.get( - type.stringValue().toLowerCase(), - format.stringValue().toLowerCase())); + return new ExprStringValue( + formats.get(type.stringValue().toLowerCase(), format.stringValue().toLowerCase())); } return ExprNullValue.of(); @@ -1521,8 +1648,7 @@ private ExprValue exprGetFormat(ExprValue type, ExprValue format) { * @return ExprValue. */ private ExprValue exprHour(ExprValue time) { - return new ExprIntegerValue( - HOURS.between(LocalTime.MIN, time.timeValue())); + return new ExprIntegerValue(HOURS.between(LocalTime.MIN, time.timeValue())); } /** @@ -1533,9 +1659,7 @@ private ExprValue exprHour(ExprValue time) { */ private LocalDate getLastDay(LocalDate today) { return LocalDate.of( - today.getYear(), - today.getMonth(), - today.getMonth().length(today.isLeapYear())); + today.getYear(), today.getMonth(), today.getMonth().length(today.isLeapYear())); } /** @@ -1560,11 +1684,9 @@ private ExprValue exprLastDayToday(Clock clock) { /** * Following MySQL, function receives arguments of type double and rounds them before use. - * Furthermore: - * - zero year interpreted as 2000 - * - negative year is not accepted - * - @dayOfYear should be greater than 1 - * - if @dayOfYear is greater than 365/366, calculation goes to the next year(s) + * Furthermore: - zero year interpreted as 2000 - negative year is not accepted - @dayOfYear + * should be greater than 1 - if @dayOfYear is greater than 365/366, calculation goes to the next + * year(s) * * @param yearExpr year * @param dayOfYearExp day of the @year, starting from 1 @@ -1580,12 +1702,13 @@ private ExprValue exprMakeDate(ExprValue yearExpr, ExprValue dayOfYearExp) { if (0 == year) { year = 2000; } - return new ExprDateValue(LocalDate.ofYearDay((int)year, 1).plusDays(dayOfYear - 1)); + return new ExprDateValue(LocalDate.ofYearDay((int) year, 1).plusDays(dayOfYear - 1)); } /** * Following MySQL, function receives arguments of type double. @hour and @minute are rounded, * while @second used as is, including fraction part. + * * @param hourExpr hour * @param minuteExpr minute * @param secondExpr second @@ -1598,8 +1721,9 @@ private ExprValue exprMakeTime(ExprValue hourExpr, ExprValue minuteExpr, ExprVal if (0 > hour || 0 > minute || 0 > second) { return ExprNullValue.of(); } - return new ExprTimeValue(LocalTime.parse(String.format("%02d:%02d:%012.9f", - hour, minute, second), DateTimeFormatter.ISO_TIME)); + return new ExprTimeValue( + LocalTime.parse( + String.format("%02d:%02d:%012.9f", hour, minute, second), DateTimeFormatter.ISO_TIME)); } /** @@ -1620,8 +1744,7 @@ private ExprValue exprMicrosecond(ExprValue time) { * @return ExprValue. */ private ExprValue exprMinute(ExprValue time) { - return new ExprIntegerValue( - (MINUTES.between(LocalTime.MIN, time.timeValue()) % 60)); + return new ExprIntegerValue((MINUTES.between(LocalTime.MIN, time.timeValue()) % 60)); } /** @@ -1631,8 +1754,7 @@ private ExprValue exprMinute(ExprValue time) { * @return ExprValue. */ private ExprValue exprMinuteOfDay(ExprValue time) { - return new ExprIntegerValue( - MINUTES.between(LocalTime.MIN, time.timeValue())); + return new ExprIntegerValue(MINUTES.between(LocalTime.MIN, time.timeValue())); } /** @@ -1675,8 +1797,7 @@ private LocalDate parseDatePeriod(Integer period) { } /** - * Adds N months to period P (in the format YYMM or YYYYMM). - * Returns a value in the format YYYYMM. + * Adds N months to period P (in the format YYMM or YYYYMM). Returns a value in the format YYYYMM. * * @param period Period in the format YYMM or YYYYMM. * @param months Amount of months to add. @@ -1684,19 +1805,20 @@ private LocalDate parseDatePeriod(Integer period) { */ private ExprValue exprPeriodAdd(ExprValue period, ExprValue months) { // We should add a day to make string parsable and remove it afterwards - var input = period.integerValue() * 100 + 1; // adds 01 to end of the string + var input = period.integerValue() * 100 + 1; // adds 01 to end of the string var parsedDate = parseDatePeriod(input); if (parsedDate == null) { return ExprNullValue.of(); } var res = DATE_FORMATTER_LONG_YEAR.format(parsedDate.plusMonths(months.integerValue())); - return new ExprIntegerValue(Integer.parseInt( - res.substring(0, res.length() - 2))); // Remove the day part, .eg. 20070101 -> 200701 + return new ExprIntegerValue( + Integer.parseInt( + res.substring(0, res.length() - 2))); // Remove the day part, .eg. 20070101 -> 200701 } /** - * Returns the number of months between periods P1 and P2. - * P1 and P2 should be in the format YYMM or YYYYMM. + * Returns the number of months between periods P1 and P2. P1 and P2 should be in the format YYMM + * or YYYYMM. * * @param period1 Period in the format YYMM or YYYYMM. * @param period2 Period in the format YYMM or YYYYMM. @@ -1724,6 +1846,7 @@ private ExprValue exprQuarter(ExprValue date) { /** * Returns TIME value of sec_to_time function for an INTEGER or LONG arguments. + * * @param totalSeconds The total number of seconds * @return A TIME value */ @@ -1732,17 +1855,17 @@ private ExprValue exprSecToTime(ExprValue totalSeconds) { } /** - * Helper function which obtains the decimal portion of the seconds value passed in. - * Uses BigDecimal to prevent issues with math on floating point numbers. - * Return is formatted to be used with Duration.ofSeconds(); + * Helper function which obtains the decimal portion of the seconds value passed in. Uses + * BigDecimal to prevent issues with math on floating point numbers. Return is formatted to be + * used with Duration.ofSeconds(); * * @param seconds and ExprDoubleValue or ExprFloatValue for the seconds * @return A LONG representing the nanoseconds portion */ private long formatNanos(ExprValue seconds) { - //Convert ExprValue to BigDecimal + // Convert ExprValue to BigDecimal BigDecimal formattedNanos = BigDecimal.valueOf(seconds.doubleValue()); - //Extract only the nanosecond part + // Extract only the nanosecond part formattedNanos = formattedNanos.subtract(BigDecimal.valueOf(formattedNanos.intValue())); return formattedNanos.scaleByPowerOfTen(9).longValue(); @@ -1750,6 +1873,7 @@ private long formatNanos(ExprValue seconds) { /** * Returns TIME value of sec_to_time function for FLOAT or DOUBLE arguments. + * * @param totalSeconds The total number of seconds * @return A TIME value */ @@ -1767,8 +1891,7 @@ private ExprValue exprSecToTimeWithNanos(ExprValue totalSeconds) { * @return ExprValue. */ private ExprValue exprSecond(ExprValue time) { - return new ExprIntegerValue( - (SECONDS.between(LocalTime.MIN, time.timeValue()) % 60)); + return new ExprIntegerValue((SECONDS.between(LocalTime.MIN, time.timeValue()) % 60)); } /** @@ -1779,8 +1902,8 @@ private ExprValue exprSecond(ExprValue time) { * @param days ExprValue of Long type, representing the number of days to subtract. * @return Date/Datetime resulted from days subtracted to date. */ - private ExprValue exprSubDateDays(FunctionProperties functionProperties, - ExprValue date, ExprValue days) { + private ExprValue exprSubDateDays( + FunctionProperties functionProperties, ExprValue date, ExprValue days) { return exprDateApplyDays(functionProperties, date, days.longValue(), false); } @@ -1792,8 +1915,8 @@ private ExprValue exprSubDateDays(FunctionProperties functionProperties, * @param expr ExprValue of Interval type, the temporal amount to subtract. * @return Datetime resulted from expr subtracted to `datetime`. */ - private ExprValue exprSubDateInterval(FunctionProperties functionProperties, - ExprValue datetime, ExprValue expr) { + private ExprValue exprSubDateInterval( + FunctionProperties functionProperties, ExprValue datetime, ExprValue expr) { return exprDateApplyInterval(functionProperties, datetime, expr.intervalValue(), false); } @@ -1804,14 +1927,13 @@ private ExprValue exprSubDateInterval(FunctionProperties functionProperties, * @param temporalDelta A Date/Time/Datetime/Timestamp to subtract time from. * @return A value calculated. */ - private ExprValue exprSubTime(FunctionProperties functionProperties, - ExprValue temporal, ExprValue temporalDelta) { + private ExprValue exprSubTime( + FunctionProperties functionProperties, ExprValue temporal, ExprValue temporalDelta) { return exprApplyTime(functionProperties, temporal, temporalDelta, false); } - private ExprValue exprStrToDate(FunctionProperties fp, - ExprValue dateTimeExpr, - ExprValue formatStringExp) { + private ExprValue exprStrToDate( + FunctionProperties fp, ExprValue dateTimeExpr, ExprValue formatStringExp) { return DateTimeFormatterUtil.parseStringWithDateOrTime(fp, dateTimeExpr, formatStringExp); } @@ -1838,8 +1960,8 @@ private ExprValue exprTime(ExprValue exprValue) { */ private ExprValue exprTimeDiff(ExprValue first, ExprValue second) { // java inverses the value, so we have to swap 1 and 2 - return new ExprTimeValue(LocalTime.MIN.plus( - Duration.between(second.timeValue(), first.timeValue()))); + return new ExprTimeValue( + LocalTime.MIN.plus(Duration.between(second.timeValue(), first.timeValue()))); } /** @@ -1852,9 +1974,8 @@ private ExprValue exprTimeToSec(ExprValue time) { return new ExprLongValue(time.timeValue().toSecondOfDay()); } - private ExprValue exprTimestampAdd(ExprValue partExpr, - ExprValue amountExpr, - ExprValue datetimeExpr) { + private ExprValue exprTimestampAdd( + ExprValue partExpr, ExprValue amountExpr, ExprValue datetimeExpr) { String part = partExpr.stringValue(); int amount = amountExpr.integerValue(); LocalDateTime datetime = datetimeExpr.datetimeValue(); @@ -1895,13 +2016,9 @@ private ExprValue exprTimestampAdd(ExprValue partExpr, return new ExprDatetimeValue(datetime.plus(amount, temporalUnit)); } - private ExprValue exprTimestampAddForTimeType(Clock clock, - ExprValue partExpr, - ExprValue amountExpr, - ExprValue timeExpr) { - LocalDateTime datetime = LocalDateTime.of( - formatNow(clock).toLocalDate(), - timeExpr.timeValue()); + private ExprValue exprTimestampAddForTimeType( + Clock clock, ExprValue partExpr, ExprValue amountExpr, ExprValue timeExpr) { + LocalDateTime datetime = LocalDateTime.of(formatNow(clock).toLocalDate(), timeExpr.timeValue()); return exprTimestampAdd(partExpr, amountExpr, new ExprDatetimeValue(datetime)); } @@ -1942,19 +2059,13 @@ private ExprValue getTimeDifference(String part, LocalDateTime startTime, LocalD } private ExprValue exprTimestampDiff( - ExprValue partExpr, - ExprValue startTimeExpr, - ExprValue endTimeExpr) { + ExprValue partExpr, ExprValue startTimeExpr, ExprValue endTimeExpr) { return getTimeDifference( - partExpr.stringValue(), - startTimeExpr.datetimeValue(), - endTimeExpr.datetimeValue()); + partExpr.stringValue(), startTimeExpr.datetimeValue(), endTimeExpr.datetimeValue()); } - private ExprValue exprTimestampDiffForTimeType(FunctionProperties fp, - ExprValue partExpr, - ExprValue startTimeExpr, - ExprValue endTimeExpr) { + private ExprValue exprTimestampDiffForTimeType( + FunctionProperties fp, ExprValue partExpr, ExprValue startTimeExpr, ExprValue endTimeExpr) { return getTimeDifference( partExpr.stringValue(), extractDateTime(startTimeExpr, fp), @@ -1988,8 +2099,8 @@ private ExprValue exprUtcTime(FunctionProperties functionProperties) { * @return ExprValue. */ private ExprValue exprUtcTimeStamp(FunctionProperties functionProperties) { - var zdt = ZonedDateTime.now(functionProperties.getQueryStartClock()) - .withZoneSameInstant(UTC_ZONE_ID); + var zdt = + ZonedDateTime.now(functionProperties.getQueryStartClock()).withZoneSameInstant(UTC_ZONE_ID); return new ExprDatetimeValue(zdt.toLocalDateTime()); } @@ -2027,25 +2138,25 @@ private DateTimeFormatter getFormatter(int dateAsInt) { throw new DateTimeException("Integer argument was out of range"); } - //Check below from YYYYMMDD - MMDD which format should be used + // Check below from YYYYMMDD - MMDD which format should be used switch (length) { - //Check if dateAsInt is at least 8 digits long + // Check if dateAsInt is at least 8 digits long case FULL_DATE_LENGTH: return DATE_FORMATTER_LONG_YEAR; - //Check if dateAsInt is at least 6 digits long + // Check if dateAsInt is at least 6 digits long case SHORT_DATE_LENGTH: return DATE_FORMATTER_SHORT_YEAR; - //Check if dateAsInt is at least 5 digits long + // Check if dateAsInt is at least 5 digits long case SINGLE_DIGIT_YEAR_DATE_LENGTH: return DATE_FORMATTER_SINGLE_DIGIT_YEAR; - //Check if dateAsInt is at least 4 digits long + // Check if dateAsInt is at least 4 digits long case NO_YEAR_DATE_LENGTH: return DATE_FORMATTER_NO_YEAR; - //Check if dateAsInt is at least 3 digits long + // Check if dateAsInt is at least 3 digits long case SINGLE_DIGIT_MONTH_DATE_LENGTH: return DATE_FORMATTER_SINGLE_DIGIT_MONTH; @@ -2064,15 +2175,16 @@ private DateTimeFormatter getFormatter(int dateAsInt) { */ private ExprValue exprToSecondsForIntType(ExprValue dateExpr) { try { - //Attempt to parse integer argument as date - LocalDate date = LocalDate.parse(String.valueOf(dateExpr.integerValue()), - getFormatter(dateExpr.integerValue())); + // Attempt to parse integer argument as date + LocalDate date = + LocalDate.parse( + String.valueOf(dateExpr.integerValue()), getFormatter(dateExpr.integerValue())); - return new ExprLongValue(date.toEpochSecond(LocalTime.MIN, ZoneOffset.UTC) - + DAYS_0000_TO_1970 * SECONDS_PER_DAY); + return new ExprLongValue( + date.toEpochSecond(LocalTime.MIN, ZoneOffset.UTC) + DAYS_0000_TO_1970 * SECONDS_PER_DAY); } catch (DateTimeException ignored) { - //Return null if parsing error + // Return null if parsing error return ExprNullValue.of(); } } @@ -2121,12 +2233,14 @@ private ExprValue unixTimeStampOf(ExprValue value) { private Double unixTimeStampOfImpl(ExprValue value) { // Also, according to MySQL documentation: // The date argument may be a DATE, DATETIME, or TIMESTAMP ... - switch ((ExprCoreType)value.type()) { - case DATE: return value.dateValue().toEpochSecond(LocalTime.MIN, ZoneOffset.UTC) + 0d; - case DATETIME: return value.datetimeValue().toEpochSecond(ZoneOffset.UTC) - + value.datetimeValue().getNano() / 1E9; - case TIMESTAMP: return value.timestampValue().getEpochSecond() - + value.timestampValue().getNano() / 1E9; + switch ((ExprCoreType) value.type()) { + case DATE: + return value.dateValue().toEpochSecond(LocalTime.MIN, ZoneOffset.UTC) + 0d; + case DATETIME: + return value.datetimeValue().toEpochSecond(ZoneOffset.UTC) + + value.datetimeValue().getNano() / 1E9; + case TIMESTAMP: + return value.timestampValue().getEpochSecond() + value.timestampValue().getNano() / 1E9; default: // ... or a number in YYMMDD, YYMMDDhhmmss, YYYYMMDD, or YYYYMMDDhhmmss format. // If the argument includes a time part, it may optionally include a fractional @@ -2172,8 +2286,8 @@ private Double unixTimeStampOfImpl(ExprValue value) { } /** - * Week for date implementation for ExprValue. - * When mode is not specified default value mode 0 is used for default_week_format. + * Week for date implementation for ExprValue. When mode is not specified default value mode 0 is + * used for default_week_format. * * @param date ExprValue of Date/Datetime/Timestamp/String type. * @return ExprValue. @@ -2203,12 +2317,11 @@ private ExprIntegerValue extractYearweek(LocalDate date, int mode) { // Needed to align with MySQL. Due to how modes for this function work. // See description of modes here ... // https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_week - int modeJava = CalendarLookup.getWeekNumber(mode, date) != 0 ? mode : - mode <= 4 ? 2 : - 7; + int modeJava = CalendarLookup.getWeekNumber(mode, date) != 0 ? mode : mode <= 4 ? 2 : 7; - int formatted = CalendarLookup.getYearNumber(modeJava, date) * 100 - + CalendarLookup.getWeekNumber(modeJava, date); + int formatted = + CalendarLookup.getYearNumber(modeJava, date) * 100 + + CalendarLookup.getWeekNumber(modeJava, date); return new ExprIntegerValue(formatted); } @@ -2224,8 +2337,8 @@ private ExprValue exprYearweek(ExprValue date, ExprValue mode) { } /** - * Yearweek for date implementation for ExprValue. - * When mode is not specified default value mode 0 is used. + * Yearweek for date implementation for ExprValue. When mode is not specified default value mode 0 + * is used. * * @param date ExprValue of Date/Datetime/Time/Timestamp/String type. * @return ExprValue. @@ -2248,19 +2361,22 @@ private LocalDateTime formatNow(Clock clock) { /** * Prepare LocalDateTime value. Truncate fractional second part according to the argument. - * @param fsp argument is given to specify a fractional seconds precision from 0 to 6, - * the return value includes a fractional seconds part of that many digits. + * + * @param fsp argument is given to specify a fractional seconds precision from 0 to 6, the return + * value includes a fractional seconds part of that many digits. * @return LocalDateTime object. */ - private LocalDateTime formatNow(Clock clock, Integer fsp) { + private LocalDateTime formatNow(Clock clock, Integer fsp) { var res = LocalDateTime.now(clock); var defaultPrecision = 9; // There are 10^9 nanoseconds in one second if (fsp < 0 || fsp > 6) { // Check that the argument is in the allowed range [0, 6] throw new IllegalArgumentException( String.format("Invalid `fsp` value: %d, allowed 0 to 6", fsp)); } - var nano = new BigDecimal(res.getNano()) - .setScale(fsp - defaultPrecision, RoundingMode.DOWN).intValue(); + var nano = + new BigDecimal(res.getNano()) + .setScale(fsp - defaultPrecision, RoundingMode.DOWN) + .intValue(); return res.withNano(nano); } } diff --git a/core/src/main/java/org/opensearch/sql/expression/datetime/IntervalClause.java b/core/src/main/java/org/opensearch/sql/expression/datetime/IntervalClause.java index 3df8489b20..5170d49fc7 100644 --- a/core/src/main/java/org/opensearch/sql/expression/datetime/IntervalClause.java +++ b/core/src/main/java/org/opensearch/sql/expression/datetime/IntervalClause.java @@ -3,7 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ - package org.opensearch.sql.expression.datetime; import static org.opensearch.sql.data.model.ExprValueUtils.getIntegerValue; @@ -45,7 +44,8 @@ public void register(BuiltinFunctionRepository repository) { } private DefaultFunctionResolver interval() { - return define(BuiltinFunctionName.INTERVAL.getName(), + return define( + BuiltinFunctionName.INTERVAL.getName(), impl(nullMissingHandling(IntervalClause::interval), INTERVAL, INTEGER, STRING), impl(nullMissingHandling(IntervalClause::interval), INTERVAL, LONG, STRING)); } diff --git a/core/src/main/java/org/opensearch/sql/expression/env/Environment.java b/core/src/main/java/org/opensearch/sql/expression/env/Environment.java index d96d0c0a50..b1377f22ae 100644 --- a/core/src/main/java/org/opensearch/sql/expression/env/Environment.java +++ b/core/src/main/java/org/opensearch/sql/expression/env/Environment.java @@ -3,33 +3,30 @@ * SPDX-License-Identifier: Apache-2.0 */ - package org.opensearch.sql.expression.env; /** * The definition of the environment. - * @param the type of expression + * + * @param the type of expression * @param the type of expression value */ public interface Environment { - /** - * resolve the value of expression from the environment. - */ + /** resolve the value of expression from the environment. */ V resolve(E var); /** * Extend the environment. * - * @param env environment - * @param expr expression. - * @param value expression value. - * @param the type of expression + * @param env environment + * @param expr expression. + * @param value expression value. + * @param the type of expression * @param the type of expression value * @return extended environment. */ - static Environment extendEnv( - Environment env, E expr, V value) { + static Environment extendEnv(Environment env, E expr, V value) { return var -> { if (var.equals(expr)) { return value; diff --git a/core/src/main/java/org/opensearch/sql/expression/function/BuiltinFunctionName.java b/core/src/main/java/org/opensearch/sql/expression/function/BuiltinFunctionName.java index 728712f537..f50fa927b8 100644 --- a/core/src/main/java/org/opensearch/sql/expression/function/BuiltinFunctionName.java +++ b/core/src/main/java/org/opensearch/sql/expression/function/BuiltinFunctionName.java @@ -12,15 +12,11 @@ import lombok.Getter; import lombok.RequiredArgsConstructor; -/** - * Builtin Function Name. - */ +/** Builtin Function Name. */ @Getter @RequiredArgsConstructor public enum BuiltinFunctionName { - /** - * Mathematical Functions. - */ + /** Mathematical Functions. */ ABS(FunctionName.of("abs")), CEIL(FunctionName.of("ceil")), CEILING(FunctionName.of("ceiling")), @@ -59,9 +55,7 @@ public enum BuiltinFunctionName { SIN(FunctionName.of("sin")), TAN(FunctionName.of("tan")), - /** - * Date and Time Functions. - */ + /** Date and Time Functions. */ ADDDATE(FunctionName.of("adddate")), ADDTIME(FunctionName.of("addtime")), CONVERT_TZ(FunctionName.of("convert_tz")), @@ -135,14 +129,10 @@ public enum BuiltinFunctionName { LOCALTIMESTAMP(FunctionName.of("localtimestamp")), SYSDATE(FunctionName.of("sysdate")), - /** - * Text Functions. - */ + /** Text Functions. */ TOSTRING(FunctionName.of("tostring")), - /** - * Arithmetic Operators. - */ + /** Arithmetic Operators. */ ADD(FunctionName.of("+")), ADDFUNCTION(FunctionName.of("add")), DIVIDE(FunctionName.of("/")), @@ -155,9 +145,7 @@ public enum BuiltinFunctionName { SUBTRACT(FunctionName.of("-")), SUBTRACTFUNCTION(FunctionName.of("subtract")), - /** - * Boolean Operators. - */ + /** Boolean Operators. */ AND(FunctionName.of("and")), OR(FunctionName.of("or")), XOR(FunctionName.of("xor")), @@ -171,9 +159,7 @@ public enum BuiltinFunctionName { LIKE(FunctionName.of("like")), NOT_LIKE(FunctionName.of("not like")), - /** - * Aggregation Function. - */ + /** Aggregation Function. */ AVG(FunctionName.of("avg")), SUM(FunctionName.of("sum")), COUNT(FunctionName.of("count")), @@ -192,9 +178,7 @@ public enum BuiltinFunctionName { // Not always an aggregation query NESTED(FunctionName.of("nested")), - /** - * Text Functions. - */ + /** Text Functions. */ ASCII(FunctionName.of("ascii")), CONCAT(FunctionName.of("concat")), CONCAT_WS(FunctionName.of("concat_ws")), @@ -215,9 +199,7 @@ public enum BuiltinFunctionName { TRIM(FunctionName.of("trim")), UPPER(FunctionName.of("upper")), - /** - * NULL Test. - */ + /** NULL Test. */ IS_NULL(FunctionName.of("is null")), IS_NOT_NULL(FunctionName.of("is not null")), IFNULL(FunctionName.of("ifnull")), @@ -231,9 +213,7 @@ public enum BuiltinFunctionName { INTERVAL(FunctionName.of("interval")), - /** - * Data Type Convert Function. - */ + /** Data Type Convert Function. */ CAST_TO_STRING(FunctionName.of("cast_to_string")), CAST_TO_BYTE(FunctionName.of("cast_to_byte")), CAST_TO_SHORT(FunctionName.of("cast_to_short")), @@ -248,9 +228,7 @@ public enum BuiltinFunctionName { CAST_TO_DATETIME(FunctionName.of("cast_to_datetime")), TYPEOF(FunctionName.of("typeof")), - /** - * Relevance Function. - */ + /** Relevance Function. */ MATCH(FunctionName.of("match")), SIMPLE_QUERY_STRING(FunctionName.of("simple_query_string")), MATCH_PHRASE(FunctionName.of("match_phrase")), @@ -264,9 +242,7 @@ public enum BuiltinFunctionName { SCOREQUERY(FunctionName.of("scorequery")), SCORE_QUERY(FunctionName.of("score_query")), - /** - * Legacy Relevance Function. - */ + /** Legacy Relevance Function. */ QUERY(FunctionName.of("query")), MATCH_QUERY(FunctionName.of("match_query")), MATCHQUERY(FunctionName.of("matchquery")), diff --git a/core/src/main/java/org/opensearch/sql/expression/function/BuiltinFunctionRepository.java b/core/src/main/java/org/opensearch/sql/expression/function/BuiltinFunctionRepository.java index 0eb11a9280..2e16d5f01f 100644 --- a/core/src/main/java/org/opensearch/sql/expression/function/BuiltinFunctionRepository.java +++ b/core/src/main/java/org/opensearch/sql/expression/function/BuiltinFunctionRepository.java @@ -38,10 +38,8 @@ import org.opensearch.sql.storage.StorageEngine; /** - * Builtin Function Repository. - * Repository registers datasource specific functions under datasource namespace and - * universal functions under default namespace. - * + * Builtin Function Repository. Repository registers datasource specific functions under datasource + * namespace and universal functions under default namespace. */ public class BuiltinFunctionRepository { @@ -96,23 +94,20 @@ public void register(FunctionResolver resolver) { functionResolverMap.put(resolver.getFunctionName(), resolver); } - /** - * Compile FunctionExpression using core function resolver. - * - */ - public FunctionImplementation compile(FunctionProperties functionProperties, - FunctionName functionName, List expressions) { + /** Compile FunctionExpression using core function resolver. */ + public FunctionImplementation compile( + FunctionProperties functionProperties, + FunctionName functionName, + List expressions) { return compile(functionProperties, Collections.emptyList(), functionName, expressions); } - - /** - * Compile FunctionExpression within {@link StorageEngine} provided {@link FunctionResolver}. - */ - public FunctionImplementation compile(FunctionProperties functionProperties, - Collection dataSourceFunctionResolver, - FunctionName functionName, - List expressions) { + /** Compile FunctionExpression within {@link StorageEngine} provided {@link FunctionResolver}. */ + public FunctionImplementation compile( + FunctionProperties functionProperties, + Collection dataSourceFunctionResolver, + FunctionName functionName, + List expressions) { FunctionBuilder resolvedFunctionBuilder = resolve( dataSourceFunctionResolver, @@ -134,8 +129,9 @@ public FunctionImplementation compile(FunctionProperties functionProperties, public FunctionBuilder resolve( Collection dataSourceFunctionResolver, FunctionSignature functionSignature) { - Map dataSourceFunctionMap = dataSourceFunctionResolver.stream() - .collect(Collectors.toMap(FunctionResolver::getFunctionName, t -> t)); + Map dataSourceFunctionMap = + dataSourceFunctionResolver.stream() + .collect(Collectors.toMap(FunctionResolver::getFunctionName, t -> t)); // first, resolve in datasource provide function resolver. // second, resolve in builtin function resolver. @@ -171,14 +167,13 @@ private Optional resolve( } /** - * Wrap resolved function builder's arguments by cast function to cast input expression value - * to value of target type at runtime. For example, suppose unresolved signature is - * equal(BOOL,STRING) and its resolved function builder is F with signature equal(BOOL,BOOL). - * In this case, wrap F and return equal(BOOL, cast_to_bool(STRING)). + * Wrap resolved function builder's arguments by cast function to cast input expression value to + * value of target type at runtime. For example, suppose unresolved signature is + * equal(BOOL,STRING) and its resolved function builder is F with signature equal(BOOL,BOOL). In + * this case, wrap F and return equal(BOOL, cast_to_bool(STRING)). */ - private FunctionBuilder castArguments(List sourceTypes, - List targetTypes, - FunctionBuilder funcBuilder) { + private FunctionBuilder castArguments( + List sourceTypes, List targetTypes, FunctionBuilder funcBuilder) { return (fp, arguments) -> { List argsCasted = new ArrayList<>(); for (int i = 0; i < arguments.size(); i++) { @@ -208,10 +203,10 @@ private boolean isCastRequired(ExprType sourceType, ExprType targetType) { private Function cast(Expression arg, ExprType targetType) { FunctionName castFunctionName = getCastFunctionName(targetType); if (castFunctionName == null) { - throw new ExpressionEvaluationException(StringUtils.format( - "Type conversion to type %s is not supported", targetType)); + throw new ExpressionEvaluationException( + StringUtils.format("Type conversion to type %s is not supported", targetType)); } - return functionProperties -> (Expression) compile(functionProperties, - castFunctionName, List.of(arg)); + return functionProperties -> + (Expression) compile(functionProperties, castFunctionName, List.of(arg)); } } diff --git a/core/src/main/java/org/opensearch/sql/expression/function/DefaultFunctionResolver.java b/core/src/main/java/org/opensearch/sql/expression/function/DefaultFunctionResolver.java index a28fa7e0ad..5d0f31594b 100644 --- a/core/src/main/java/org/opensearch/sql/expression/function/DefaultFunctionResolver.java +++ b/core/src/main/java/org/opensearch/sql/expression/function/DefaultFunctionResolver.java @@ -18,52 +18,53 @@ import org.opensearch.sql.exception.ExpressionEvaluationException; /** - * The Function Resolver hold the overload {@link FunctionBuilder} implementation. - * is composed by {@link FunctionName} which identified the function name - * and a map of {@link FunctionSignature} and {@link FunctionBuilder} - * to represent the overloaded implementation + * The Function Resolver hold the overload {@link FunctionBuilder} implementation. is composed by + * {@link FunctionName} which identified the function name and a map of {@link FunctionSignature} + * and {@link FunctionBuilder} to represent the overloaded implementation */ @Builder @RequiredArgsConstructor public class DefaultFunctionResolver implements FunctionResolver { - @Getter - private final FunctionName functionName; + @Getter private final FunctionName functionName; + @Singular("functionBundle") private final Map functionBundle; /** - * Resolve the {@link FunctionBuilder} by using input {@link FunctionSignature}. - * If the {@link FunctionBuilder} exactly match the input {@link FunctionSignature}, return it. - * If applying the widening rule, found the most match one, return it. - * If nothing found, throw {@link ExpressionEvaluationException} + * Resolve the {@link FunctionBuilder} by using input {@link FunctionSignature}. If the {@link + * FunctionBuilder} exactly match the input {@link FunctionSignature}, return it. If applying the + * widening rule, found the most match one, return it. If nothing found, throw {@link + * ExpressionEvaluationException} * * @return function signature and its builder */ @Override public Pair resolve(FunctionSignature unresolvedSignature) { - PriorityQueue> functionMatchQueue = new PriorityQueue<>( - Map.Entry.comparingByKey()); + PriorityQueue> functionMatchQueue = + new PriorityQueue<>(Map.Entry.comparingByKey()); for (FunctionSignature functionSignature : functionBundle.keySet()) { functionMatchQueue.add( - new AbstractMap.SimpleEntry<>(unresolvedSignature.match(functionSignature), - functionSignature)); + new AbstractMap.SimpleEntry<>( + unresolvedSignature.match(functionSignature), functionSignature)); } Map.Entry bestMatchEntry = functionMatchQueue.peek(); if (FunctionSignature.isVarArgFunction(bestMatchEntry.getValue().getParamTypeList()) - && (unresolvedSignature.getParamTypeList().isEmpty() + && (unresolvedSignature.getParamTypeList().isEmpty() || unresolvedSignature.getParamTypeList().size() > 9)) { throw new ExpressionEvaluationException( - String.format("%s function expected 1-9 arguments, but got %d", - functionName, unresolvedSignature.getParamTypeList().size())); + String.format( + "%s function expected 1-9 arguments, but got %d", + functionName, unresolvedSignature.getParamTypeList().size())); } if (FunctionSignature.NOT_MATCH.equals(bestMatchEntry.getKey()) - && !FunctionSignature.isVarArgFunction(bestMatchEntry.getValue().getParamTypeList())) { + && !FunctionSignature.isVarArgFunction(bestMatchEntry.getValue().getParamTypeList())) { throw new ExpressionEvaluationException( - String.format("%s function expected %s, but get %s", functionName, + String.format( + "%s function expected %s, but get %s", + functionName, formatFunctions(functionBundle.keySet()), - unresolvedSignature.formatTypes() - )); + unresolvedSignature.formatTypes())); } else { FunctionSignature resolvedSignature = bestMatchEntry.getValue(); return Pair.of(resolvedSignature, functionBundle.get(resolvedSignature)); @@ -71,7 +72,8 @@ public Pair resolve(FunctionSignature unreso } private String formatFunctions(Set functionSignatures) { - return functionSignatures.stream().map(FunctionSignature::formatTypes) + return functionSignatures.stream() + .map(FunctionSignature::formatTypes) .collect(Collectors.joining(",", "{", "}")); } } diff --git a/core/src/main/java/org/opensearch/sql/expression/function/FunctionBuilder.java b/core/src/main/java/org/opensearch/sql/expression/function/FunctionBuilder.java index b6e32a1d27..a529885c16 100644 --- a/core/src/main/java/org/opensearch/sql/expression/function/FunctionBuilder.java +++ b/core/src/main/java/org/opensearch/sql/expression/function/FunctionBuilder.java @@ -3,15 +3,14 @@ * SPDX-License-Identifier: Apache-2.0 */ - package org.opensearch.sql.expression.function; import java.util.List; import org.opensearch.sql.expression.Expression; /** - * The definition of function which create {@link FunctionImplementation} - * from input {@link Expression} list. + * The definition of function which create {@link FunctionImplementation} from input {@link + * Expression} list. */ public interface FunctionBuilder { @@ -19,7 +18,7 @@ public interface FunctionBuilder { * Create {@link FunctionImplementation} from input {@link Expression} list. * * @param functionProperties context for function execution. - * @param arguments {@link Expression} list. + * @param arguments {@link Expression} list. * @return {@link FunctionImplementation} */ FunctionImplementation apply(FunctionProperties functionProperties, List arguments); diff --git a/core/src/main/java/org/opensearch/sql/expression/function/FunctionDSL.java b/core/src/main/java/org/opensearch/sql/expression/function/FunctionDSL.java index c57d96caea..8ebbfd3a3c 100644 --- a/core/src/main/java/org/opensearch/sql/expression/function/FunctionDSL.java +++ b/core/src/main/java/org/opensearch/sql/expression/function/FunctionDSL.java @@ -3,7 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ - package org.opensearch.sql.expression.function; import java.util.Arrays; @@ -21,21 +20,19 @@ import org.opensearch.sql.expression.env.Environment; import org.opensearch.sql.expression.function.DefaultFunctionResolver.DefaultFunctionResolverBuilder; -/** - * Function Define Utility. - */ +/** Function Define Utility. */ @UtilityClass public class FunctionDSL { /** * Define overloaded function with implementation. * * @param functionName function name. - * @param functions a list of function implementation. + * @param functions a list of function implementation. * @return FunctionResolver. */ - public static DefaultFunctionResolver define(FunctionName functionName, - SerializableFunction>... functions) { + public static DefaultFunctionResolver define( + FunctionName functionName, + SerializableFunction>... functions) { return define(functionName, List.of(functions)); } @@ -43,11 +40,13 @@ public static DefaultFunctionResolver define(FunctionName functionName, * Define overloaded function with implementation. * * @param functionName function name. - * @param functions a list of function implementation. + * @param functions a list of function implementation. * @return FunctionResolver. */ - public static DefaultFunctionResolver define(FunctionName functionName, List< - SerializableFunction>> functions) { + public static DefaultFunctionResolver define( + FunctionName functionName, + List>> + functions) { DefaultFunctionResolverBuilder builder = DefaultFunctionResolver.builder(); builder.functionName(functionName); @@ -58,7 +57,6 @@ public static DefaultFunctionResolver define(FunctionName functionName, List< return builder.build(); } - /** * Implementation of no args function that uses FunctionProperties. * @@ -67,8 +65,8 @@ public static DefaultFunctionResolver define(FunctionName functionName, List< * @return no args function implementation. */ public static SerializableFunction> - implWithProperties(SerializableFunction function, - ExprType returnType) { + implWithProperties( + SerializableFunction function, ExprType returnType) { return functionName -> { FunctionSignature functionSignature = new FunctionSignature(functionName, Collections.emptyList()); @@ -95,53 +93,54 @@ public String toString() { } /** - * Implementation of a function that takes one argument, returns a value, and - * requires FunctionProperties to complete. + * Implementation of a function that takes one argument, returns a value, and requires + * FunctionProperties to complete. * - * @param function {@link ExprValue} based unary function. + * @param function {@link ExprValue} based unary function. * @param returnType return type. * @param argsType argument type. * @return Unary Function Implementation. */ public static SerializableFunction> implWithProperties( - SerializableBiFunction function, - ExprType returnType, - ExprType argsType) { + SerializableBiFunction function, + ExprType returnType, + ExprType argsType) { return functionName -> { FunctionSignature functionSignature = new FunctionSignature(functionName, Collections.singletonList(argsType)); FunctionBuilder functionBuilder = - (functionProperties, arguments) -> new FunctionExpression(functionName, arguments) { - @Override - public ExprValue valueOf(Environment valueEnv) { - ExprValue value = arguments.get(0).valueOf(valueEnv); - return function.apply(functionProperties, value); - } - - @Override - public ExprType type() { - return returnType; - } - - @Override - public String toString() { - return String.format("%s(%s)", functionName, - arguments.stream() - .map(Object::toString) - .collect(Collectors.joining(", "))); - } - }; + (functionProperties, arguments) -> + new FunctionExpression(functionName, arguments) { + @Override + public ExprValue valueOf(Environment valueEnv) { + ExprValue value = arguments.get(0).valueOf(valueEnv); + return function.apply(functionProperties, value); + } + + @Override + public ExprType type() { + return returnType; + } + + @Override + public String toString() { + return String.format( + "%s(%s)", + functionName, + arguments.stream().map(Object::toString).collect(Collectors.joining(", "))); + } + }; return Pair.of(functionSignature, functionBuilder); }; } /** - * Implementation of a function that takes two arguments, returns a value, and - * requires FunctionProperties to complete. + * Implementation of a function that takes two arguments, returns a value, and requires + * FunctionProperties to complete. * - * @param function {@link ExprValue} based Binary function. + * @param function {@link ExprValue} based Binary function. * @param returnType return type. * @param args1Type first argument type. * @param args2Type second argument type. @@ -149,45 +148,46 @@ public String toString() { */ public static SerializableFunction> implWithProperties( - SerializableTriFunction function, - ExprType returnType, - ExprType args1Type, - ExprType args2Type) { + SerializableTriFunction function, + ExprType returnType, + ExprType args1Type, + ExprType args2Type) { return functionName -> { FunctionSignature functionSignature = new FunctionSignature(functionName, Arrays.asList(args1Type, args2Type)); FunctionBuilder functionBuilder = - (functionProperties, arguments) -> new FunctionExpression(functionName, arguments) { - @Override - public ExprValue valueOf(Environment valueEnv) { - ExprValue arg1 = arguments.get(0).valueOf(valueEnv); - ExprValue arg2 = arguments.get(1).valueOf(valueEnv); - return function.apply(functionProperties, arg1, arg2); - } - - @Override - public ExprType type() { - return returnType; - } - - @Override - public String toString() { - return String.format("%s(%s)", functionName, - arguments.stream() - .map(Object::toString) - .collect(Collectors.joining(", "))); - } - }; + (functionProperties, arguments) -> + new FunctionExpression(functionName, arguments) { + @Override + public ExprValue valueOf(Environment valueEnv) { + ExprValue arg1 = arguments.get(0).valueOf(valueEnv); + ExprValue arg2 = arguments.get(1).valueOf(valueEnv); + return function.apply(functionProperties, arg1, arg2); + } + + @Override + public ExprType type() { + return returnType; + } + + @Override + public String toString() { + return String.format( + "%s(%s)", + functionName, + arguments.stream().map(Object::toString).collect(Collectors.joining(", "))); + } + }; return Pair.of(functionSignature, functionBuilder); }; } /** - * Implementation of a function that takes three arguments, returns a value, and - * requires FunctionProperties to complete. + * Implementation of a function that takes three arguments, returns a value, and requires + * FunctionProperties to complete. * - * @param function {@link ExprValue} based Binary function. + * @param function {@link ExprValue} based Binary function. * @param returnType return type. * @param args1Type first argument type. * @param args2Type second argument type. @@ -196,43 +196,40 @@ public String toString() { */ public static SerializableFunction> implWithProperties( - SerializableQuadFunction< - FunctionProperties, - ExprValue, - ExprValue, - ExprValue, - ExprValue> function, - ExprType returnType, - ExprType args1Type, - ExprType args2Type, - ExprType args3Type) { + SerializableQuadFunction + function, + ExprType returnType, + ExprType args1Type, + ExprType args2Type, + ExprType args3Type) { return functionName -> { FunctionSignature functionSignature = new FunctionSignature(functionName, Arrays.asList(args1Type, args2Type, args3Type)); FunctionBuilder functionBuilder = - (functionProperties, arguments) -> new FunctionExpression(functionName, arguments) { - @Override - public ExprValue valueOf(Environment valueEnv) { - ExprValue arg1 = arguments.get(0).valueOf(valueEnv); - ExprValue arg2 = arguments.get(1).valueOf(valueEnv); - ExprValue arg3 = arguments.get(2).valueOf(valueEnv); - return function.apply(functionProperties, arg1, arg2, arg3); - } - - @Override - public ExprType type() { - return returnType; - } - - @Override - public String toString() { - return String.format("%s(%s)", functionName, - arguments.stream() - .map(Object::toString) - .collect(Collectors.joining(", "))); - } - }; + (functionProperties, arguments) -> + new FunctionExpression(functionName, arguments) { + @Override + public ExprValue valueOf(Environment valueEnv) { + ExprValue arg1 = arguments.get(0).valueOf(valueEnv); + ExprValue arg2 = arguments.get(1).valueOf(valueEnv); + ExprValue arg3 = arguments.get(2).valueOf(valueEnv); + return function.apply(functionProperties, arg1, arg2, arg3); + } + + @Override + public ExprType type() { + return returnType; + } + + @Override + public String toString() { + return String.format( + "%s(%s)", + functionName, + arguments.stream().map(Object::toString).collect(Collectors.joining(", "))); + } + }; return Pair.of(functionSignature, functionBuilder); }; } @@ -240,28 +237,25 @@ public String toString() { /** * No Arg Function Implementation. * - * @param function {@link ExprValue} based unary function. + * @param function {@link ExprValue} based unary function. * @param returnType return type. * @return Unary Function Implementation. */ public static SerializableFunction> impl( - SerializableNoArgFunction function, - ExprType returnType) { + SerializableNoArgFunction function, ExprType returnType) { return implWithProperties(fp -> function.get(), returnType); } /** * Unary Function Implementation. * - * @param function {@link ExprValue} based unary function. + * @param function {@link ExprValue} based unary function. * @param returnType return type. - * @param argsType argument type. + * @param argsType argument type. * @return Unary Function Implementation. */ public static SerializableFunction> impl( - SerializableFunction function, - ExprType returnType, - ExprType argsType) { + SerializableFunction function, ExprType returnType, ExprType argsType) { return implWithProperties((fp, arg) -> function.apply(arg), returnType, argsType); } @@ -269,10 +263,10 @@ public static SerializableFunction> impl( @@ -281,17 +275,17 @@ public static SerializableFunction - function.apply(arg1, arg2), returnType, args1Type, args2Type); + return implWithProperties( + (fp, arg1, arg2) -> function.apply(arg1, arg2), returnType, args1Type, args2Type); } /** * Triple Function Implementation. * - * @param function {@link ExprValue} based unary function. + * @param function {@link ExprValue} based unary function. * @param returnType return type. - * @param args1Type argument type. - * @param args2Type argument type. + * @param args1Type argument type. + * @param args2Type argument type. * @return Binary Function Implementation. */ public static SerializableFunction> impl( @@ -305,26 +299,31 @@ public static SerializableFunction new FunctionExpression(functionName, arguments) { - @Override - public ExprValue valueOf(Environment valueEnv) { - ExprValue arg1 = arguments.get(0).valueOf(valueEnv); - ExprValue arg2 = arguments.get(1).valueOf(valueEnv); - ExprValue arg3 = arguments.get(2).valueOf(valueEnv); - return function.apply(arg1, arg2, arg3); - } - - @Override - public ExprType type() { - return returnType; - } - - @Override - public String toString() { - return String.format("%s(%s, %s, %s)", functionName, arguments.get(0).toString(), - arguments.get(1).toString(), arguments.get(2).toString()); - } - }; + (functionProperties, arguments) -> + new FunctionExpression(functionName, arguments) { + @Override + public ExprValue valueOf(Environment valueEnv) { + ExprValue arg1 = arguments.get(0).valueOf(valueEnv); + ExprValue arg2 = arguments.get(1).valueOf(valueEnv); + ExprValue arg3 = arguments.get(2).valueOf(valueEnv); + return function.apply(arg1, arg2, arg3); + } + + @Override + public ExprType type() { + return returnType; + } + + @Override + public String toString() { + return String.format( + "%s(%s, %s, %s)", + functionName, + arguments.get(0).toString(), + arguments.get(1).toString(), + arguments.get(2).toString()); + } + }; return Pair.of(functionSignature, functionBuilder); }; } @@ -332,11 +331,11 @@ public String toString() { /** * Quadruple Function Implementation. * - * @param function {@link ExprValue} based unary function. + * @param function {@link ExprValue} based unary function. * @param returnType return type. - * @param args1Type argument type. - * @param args2Type argument type. - * @param args3Type argument type. + * @param args1Type argument type. + * @param args2Type argument type. + * @param args3Type argument type. * @return Quadruple Function Implementation. */ public static SerializableFunction> impl( @@ -349,42 +348,41 @@ public static SerializableFunction { FunctionSignature functionSignature = - new FunctionSignature(functionName, Arrays.asList( - args1Type, - args2Type, - args3Type, - args4Type)); + new FunctionSignature( + functionName, Arrays.asList(args1Type, args2Type, args3Type, args4Type)); FunctionBuilder functionBuilder = - (functionProperties, arguments) -> new FunctionExpression(functionName, arguments) { - @Override - public ExprValue valueOf(Environment valueEnv) { - ExprValue arg1 = arguments.get(0).valueOf(valueEnv); - ExprValue arg2 = arguments.get(1).valueOf(valueEnv); - ExprValue arg3 = arguments.get(2).valueOf(valueEnv); - ExprValue arg4 = arguments.get(3).valueOf(valueEnv); - return function.apply(arg1, arg2, arg3, arg4); - } - - @Override - public ExprType type() { - return returnType; - } - - @Override - public String toString() { - return String.format("%s(%s, %s, %s, %s)", functionName, arguments.get(0).toString(), - arguments.get(1).toString(), - arguments.get(2).toString(), - arguments.get(3).toString()); - } - }; + (functionProperties, arguments) -> + new FunctionExpression(functionName, arguments) { + @Override + public ExprValue valueOf(Environment valueEnv) { + ExprValue arg1 = arguments.get(0).valueOf(valueEnv); + ExprValue arg2 = arguments.get(1).valueOf(valueEnv); + ExprValue arg3 = arguments.get(2).valueOf(valueEnv); + ExprValue arg4 = arguments.get(3).valueOf(valueEnv); + return function.apply(arg1, arg2, arg3, arg4); + } + + @Override + public ExprType type() { + return returnType; + } + + @Override + public String toString() { + return String.format( + "%s(%s, %s, %s, %s)", + functionName, + arguments.get(0).toString(), + arguments.get(1).toString(), + arguments.get(2).toString(), + arguments.get(3).toString()); + } + }; return Pair.of(functionSignature, functionBuilder); }; } - /** - * Wrapper the unary ExprValue function with default NULL and MISSING handling. - */ + /** Wrapper the unary ExprValue function with default NULL and MISSING handling. */ public static SerializableFunction nullMissingHandling( SerializableFunction function) { return value -> { @@ -398,9 +396,7 @@ public static SerializableFunction nullMissingHandling( }; } - /** - * Wrapper the binary ExprValue function with default NULL and MISSING handling. - */ + /** Wrapper the binary ExprValue function with default NULL and MISSING handling. */ public static SerializableBiFunction nullMissingHandling( SerializableBiFunction function) { return (v1, v2) -> { @@ -414,9 +410,7 @@ public static SerializableBiFunction nullMissin }; } - /** - * Wrapper the triple ExprValue function with default NULL and MISSING handling. - */ + /** Wrapper the triple ExprValue function with default NULL and MISSING handling. */ public SerializableTriFunction nullMissingHandling( SerializableTriFunction function) { return (v1, v2, v3) -> { @@ -431,12 +425,12 @@ public SerializableTriFunction nullM } /** - * Wrapper the unary ExprValue function that is aware of FunctionProperties, - * with default NULL and MISSING handling. + * Wrapper the unary ExprValue function that is aware of FunctionProperties, with default NULL and + * MISSING handling. */ public static SerializableBiFunction - nullMissingHandlingWithProperties( - SerializableBiFunction implementation) { + nullMissingHandlingWithProperties( + SerializableBiFunction implementation) { return (functionProperties, v1) -> { if (v1.isMissing()) { return ExprValueUtils.missingValue(); @@ -453,8 +447,9 @@ public SerializableTriFunction nullM * with default NULL and MISSING handling. */ public static SerializableTriFunction - nullMissingHandlingWithProperties( - SerializableTriFunction implementation) { + nullMissingHandlingWithProperties( + SerializableTriFunction + implementation) { return (functionProperties, v1, v2) -> { if (v1.isMissing() || v2.isMissing()) { return ExprValueUtils.missingValue(); @@ -471,18 +466,10 @@ public SerializableTriFunction nullM * with default NULL and MISSING handling. */ public static SerializableQuadFunction< - FunctionProperties, - ExprValue, - ExprValue, - ExprValue, - ExprValue> + FunctionProperties, ExprValue, ExprValue, ExprValue, ExprValue> nullMissingHandlingWithProperties( - SerializableQuadFunction< - FunctionProperties, - ExprValue, - ExprValue, - ExprValue, - ExprValue> implementation) { + SerializableQuadFunction + implementation) { return (functionProperties, v1, v2, v3) -> { if (v1.isMissing() || v2.isMissing() || v3.isMissing()) { return ExprValueUtils.missingValue(); diff --git a/core/src/main/java/org/opensearch/sql/expression/function/FunctionImplementation.java b/core/src/main/java/org/opensearch/sql/expression/function/FunctionImplementation.java index d829e01225..4fd265a890 100644 --- a/core/src/main/java/org/opensearch/sql/expression/function/FunctionImplementation.java +++ b/core/src/main/java/org/opensearch/sql/expression/function/FunctionImplementation.java @@ -3,24 +3,17 @@ * SPDX-License-Identifier: Apache-2.0 */ - package org.opensearch.sql.expression.function; import java.util.List; import org.opensearch.sql.expression.Expression; -/** - * The definition of Function Implementation. - */ +/** The definition of Function Implementation. */ public interface FunctionImplementation { - /** - * Get Function Name. - */ + /** Get Function Name. */ FunctionName getFunctionName(); - /** - * Get Function Arguments. - */ + /** Get Function Arguments. */ List getArguments(); } diff --git a/core/src/main/java/org/opensearch/sql/expression/function/FunctionName.java b/core/src/main/java/org/opensearch/sql/expression/function/FunctionName.java index cb3d5fab92..ae2987a164 100644 --- a/core/src/main/java/org/opensearch/sql/expression/function/FunctionName.java +++ b/core/src/main/java/org/opensearch/sql/expression/function/FunctionName.java @@ -3,7 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ - package org.opensearch.sql.expression.function; import java.io.Serializable; @@ -11,14 +10,11 @@ import lombok.Getter; import lombok.RequiredArgsConstructor; -/** - * The definition of Function Name. - */ +/** The definition of Function Name. */ @EqualsAndHashCode @RequiredArgsConstructor public class FunctionName implements Serializable { - @Getter - private final String functionName; + @Getter private final String functionName; public static FunctionName of(String functionName) { return new FunctionName(functionName.toLowerCase()); diff --git a/core/src/main/java/org/opensearch/sql/expression/function/FunctionProperties.java b/core/src/main/java/org/opensearch/sql/expression/function/FunctionProperties.java index 4222748051..100c98bd38 100644 --- a/core/src/main/java/org/opensearch/sql/expression/function/FunctionProperties.java +++ b/core/src/main/java/org/opensearch/sql/expression/function/FunctionProperties.java @@ -19,9 +19,7 @@ public class FunctionProperties implements Serializable { private final Instant nowInstant; private final ZoneId currentZoneId; - /** - * By default, use current time and current timezone. - */ + /** By default, use current time and current timezone. */ public FunctionProperties() { nowInstant = Instant.now(); currentZoneId = ZoneId.systemDefault(); @@ -29,6 +27,7 @@ public FunctionProperties() { /** * Method to access current system clock. + * * @return a ticking clock that tells the time. */ public Clock getSystemClock() { @@ -36,29 +35,28 @@ public Clock getSystemClock() { } /** - * Method to get time when query began execution. - * Clock class combines an instant Supplier and a time zone. - * @return a fixed clock that returns the time execution started at. + * Method to get time when query began execution. Clock class combines an instant Supplier and a + * time zone. * + * @return a fixed clock that returns the time execution started at. */ public Clock getQueryStartClock() { return Clock.fixed(nowInstant, currentZoneId); } - /** - * Use when compiling functions that do not rely on function properties. - */ - public static final FunctionProperties None = new FunctionProperties() { - @Override - public Clock getSystemClock() { - throw new UnexpectedCallException(); - } + /** Use when compiling functions that do not rely on function properties. */ + public static final FunctionProperties None = + new FunctionProperties() { + @Override + public Clock getSystemClock() { + throw new UnexpectedCallException(); + } - @Override - public Clock getQueryStartClock() { - throw new UnexpectedCallException(); - } - }; + @Override + public Clock getQueryStartClock() { + throw new UnexpectedCallException(); + } + }; class UnexpectedCallException extends RuntimeException { public UnexpectedCallException() { diff --git a/core/src/main/java/org/opensearch/sql/expression/function/FunctionResolver.java b/core/src/main/java/org/opensearch/sql/expression/function/FunctionResolver.java index 1635b6f846..eaede1da7e 100644 --- a/core/src/main/java/org/opensearch/sql/expression/function/FunctionResolver.java +++ b/core/src/main/java/org/opensearch/sql/expression/function/FunctionResolver.java @@ -8,8 +8,8 @@ import org.apache.commons.lang3.tuple.Pair; /** - * An interface for any class that can provide a {@ref FunctionBuilder} - * given a {@ref FunctionSignature}. + * An interface for any class that can provide a {@ref FunctionBuilder} given a {@ref + * FunctionSignature}. */ public interface FunctionResolver { Pair resolve(FunctionSignature unresolvedSignature); diff --git a/core/src/main/java/org/opensearch/sql/expression/function/FunctionSignature.java b/core/src/main/java/org/opensearch/sql/expression/function/FunctionSignature.java index 0c59d71c25..665486afdc 100644 --- a/core/src/main/java/org/opensearch/sql/expression/function/FunctionSignature.java +++ b/core/src/main/java/org/opensearch/sql/expression/function/FunctionSignature.java @@ -15,9 +15,7 @@ import org.opensearch.sql.data.type.ExprType; import org.opensearch.sql.data.type.WideningTypeRule; -/** - * Function signature is composed by function name and arguments list. - */ +/** Function signature is composed by function name and arguments list. */ @Getter @RequiredArgsConstructor @EqualsAndHashCode @@ -31,9 +29,8 @@ public class FunctionSignature { /** * calculate the function signature match degree. * - * @return EXACTLY_MATCH: exactly match - * NOT_MATCH: not match - * By widening rule, the small number means better match + * @return EXACTLY_MATCH: exactly match NOT_MATCH: not match By widening rule, the small number + * means better match */ public int match(FunctionSignature functionSignature) { List functionTypeList = functionSignature.getParamTypeList(); @@ -60,18 +57,14 @@ public int match(FunctionSignature functionSignature) { return matchDegree; } - /** - * util function for formatted arguments list. - */ + /** util function for formatted arguments list. */ public String formatTypes() { return getParamTypeList().stream() .map(ExprType::typeName) .collect(Collectors.joining(",", "[", "]")); } - /** - * util function - returns true if function has variable arguments. - */ + /** util function - returns true if function has variable arguments. */ protected static boolean isVarArgFunction(List argTypes) { return argTypes.size() == 1 && argTypes.get(0) == ARRAY; } diff --git a/core/src/main/java/org/opensearch/sql/expression/function/OpenSearchFunctions.java b/core/src/main/java/org/opensearch/sql/expression/function/OpenSearchFunctions.java index c5fcb010f5..8d8928c16a 100644 --- a/core/src/main/java/org/opensearch/sql/expression/function/OpenSearchFunctions.java +++ b/core/src/main/java/org/opensearch/sql/expression/function/OpenSearchFunctions.java @@ -22,9 +22,7 @@ @UtilityClass public class OpenSearchFunctions { - /** - * Add functions specific to OpenSearch to repository. - */ + /** Add functions specific to OpenSearch to repository. */ public void register(BuiltinFunctionRepository repository) { repository.register(match_bool_prefix()); repository.register(multi_match(BuiltinFunctionName.MULTI_MATCH)); @@ -101,19 +99,20 @@ private static FunctionResolver nested() { @Override public Pair resolve( FunctionSignature unresolvedSignature) { - return Pair.of(unresolvedSignature, + return Pair.of( + unresolvedSignature, (functionProperties, arguments) -> - new FunctionExpression(BuiltinFunctionName.NESTED.getName(), arguments) { - @Override - public ExprValue valueOf(Environment valueEnv) { - return valueEnv.resolve(getArguments().get(0)); - } - - @Override - public ExprType type() { - return getArguments().get(0).type(); - } - }); + new FunctionExpression(BuiltinFunctionName.NESTED.getName(), arguments) { + @Override + public ExprValue valueOf(Environment valueEnv) { + return valueEnv.resolve(getArguments().get(0)); + } + + @Override + public ExprType type() { + return getArguments().get(0).type(); + } + }); } @Override @@ -123,9 +122,6 @@ public FunctionName getFunctionName() { }; } - - - private static FunctionResolver score(BuiltinFunctionName score) { FunctionName funcName = score.getName(); return new RelevanceFunctionResolver(funcName); @@ -135,12 +131,11 @@ public static class OpenSearchFunction extends FunctionExpression { private final FunctionName functionName; private final List arguments; - @Getter - @Setter - private boolean isScoreTracked; + @Getter @Setter private boolean isScoreTracked; /** * Required argument constructor. + * * @param functionName name of the function * @param arguments a list of expressions */ @@ -153,9 +148,10 @@ public OpenSearchFunction(FunctionName functionName, List arguments) @Override public ExprValue valueOf(Environment valueEnv) { - throw new UnsupportedOperationException(String.format( - "OpenSearch defined function [%s] is only supported in WHERE and HAVING clause.", - functionName)); + throw new UnsupportedOperationException( + String.format( + "OpenSearch defined function [%s] is only supported in WHERE and HAVING clause.", + functionName)); } @Override @@ -165,10 +161,15 @@ public ExprType type() { @Override public String toString() { - List args = arguments.stream() - .map(arg -> String.format("%s=%s", ((NamedArgumentExpression) arg) - .getArgName(), ((NamedArgumentExpression) arg).getValue().toString())) - .collect(Collectors.toList()); + List args = + arguments.stream() + .map( + arg -> + String.format( + "%s=%s", + ((NamedArgumentExpression) arg).getArgName(), + ((NamedArgumentExpression) arg).getValue().toString())) + .collect(Collectors.toList()); return String.format("%s(%s)", functionName, String.join(", ", args)); } } diff --git a/core/src/main/java/org/opensearch/sql/expression/function/RelevanceFunctionResolver.java b/core/src/main/java/org/opensearch/sql/expression/function/RelevanceFunctionResolver.java index ef0ac9226c..ae882897d0 100644 --- a/core/src/main/java/org/opensearch/sql/expression/function/RelevanceFunctionResolver.java +++ b/core/src/main/java/org/opensearch/sql/expression/function/RelevanceFunctionResolver.java @@ -14,17 +14,18 @@ import org.opensearch.sql.exception.SemanticCheckException; @RequiredArgsConstructor -public class RelevanceFunctionResolver - implements FunctionResolver { +public class RelevanceFunctionResolver implements FunctionResolver { - @Getter - private final FunctionName functionName; + @Getter private final FunctionName functionName; @Override public Pair resolve(FunctionSignature unresolvedSignature) { if (!unresolvedSignature.getFunctionName().equals(functionName)) { - throw new SemanticCheckException(String.format("Expected '%s' but got '%s'", - functionName.getFunctionName(), unresolvedSignature.getFunctionName().getFunctionName())); + throw new SemanticCheckException( + String.format( + "Expected '%s' but got '%s'", + functionName.getFunctionName(), + unresolvedSignature.getFunctionName().getFunctionName())); } List paramTypes = unresolvedSignature.getParamTypeList(); // Check if all but the first parameter are of type STRING. @@ -36,13 +37,15 @@ public Pair resolve(FunctionSignature unreso } } - FunctionBuilder buildFunction = (functionProperties, args) - -> new OpenSearchFunctions.OpenSearchFunction(functionName, args); + FunctionBuilder buildFunction = + (functionProperties, args) -> + new OpenSearchFunctions.OpenSearchFunction(functionName, args); return Pair.of(unresolvedSignature, buildFunction); } - /** Returns a helpful error message when expected parameter type does not match the - * specified parameter type. + /** + * Returns a helpful error message when expected parameter type does not match the specified + * parameter type. * * @param i 0-based index of the parameter in a function signature. * @param paramType the type of the ith parameter at run-time. @@ -50,7 +53,8 @@ public Pair resolve(FunctionSignature unreso * @return A user-friendly error message that informs of the type difference. */ private String getWrongParameterErrorMessage(int i, ExprType paramType, ExprType expectedType) { - return String.format("Expected type %s instead of %s for parameter #%d", + return String.format( + "Expected type %s instead of %s for parameter #%d", expectedType.typeName(), paramType.typeName(), i + 1); } } diff --git a/core/src/main/java/org/opensearch/sql/expression/function/SerializableBiFunction.java b/core/src/main/java/org/opensearch/sql/expression/function/SerializableBiFunction.java index 5b3aaf31f3..9f182e4c85 100644 --- a/core/src/main/java/org/opensearch/sql/expression/function/SerializableBiFunction.java +++ b/core/src/main/java/org/opensearch/sql/expression/function/SerializableBiFunction.java @@ -3,14 +3,10 @@ * SPDX-License-Identifier: Apache-2.0 */ - package org.opensearch.sql.expression.function; import java.io.Serializable; import java.util.function.BiFunction; -/** - * Serializable BiFunction. - */ -public interface SerializableBiFunction extends BiFunction, Serializable { -} +/** Serializable BiFunction. */ +public interface SerializableBiFunction extends BiFunction, Serializable {} diff --git a/core/src/main/java/org/opensearch/sql/expression/function/SerializableFunction.java b/core/src/main/java/org/opensearch/sql/expression/function/SerializableFunction.java index 467c034c39..fb3e2f2cfb 100644 --- a/core/src/main/java/org/opensearch/sql/expression/function/SerializableFunction.java +++ b/core/src/main/java/org/opensearch/sql/expression/function/SerializableFunction.java @@ -3,11 +3,9 @@ * SPDX-License-Identifier: Apache-2.0 */ - package org.opensearch.sql.expression.function; import java.io.Serializable; import java.util.function.Function; -public interface SerializableFunction extends Function, Serializable { -} +public interface SerializableFunction extends Function, Serializable {} diff --git a/core/src/main/java/org/opensearch/sql/expression/function/SerializableNoArgFunction.java b/core/src/main/java/org/opensearch/sql/expression/function/SerializableNoArgFunction.java index e68d6084b4..6eaf699bf9 100644 --- a/core/src/main/java/org/opensearch/sql/expression/function/SerializableNoArgFunction.java +++ b/core/src/main/java/org/opensearch/sql/expression/function/SerializableNoArgFunction.java @@ -3,14 +3,10 @@ * SPDX-License-Identifier: Apache-2.0 */ - package org.opensearch.sql.expression.function; import java.io.Serializable; import java.util.function.Supplier; -/** - * Serializable no argument function. - */ -public interface SerializableNoArgFunction extends Supplier, Serializable { -} +/** Serializable no argument function. */ +public interface SerializableNoArgFunction extends Supplier, Serializable {} diff --git a/core/src/main/java/org/opensearch/sql/expression/function/SerializableQuadFunction.java b/core/src/main/java/org/opensearch/sql/expression/function/SerializableQuadFunction.java index 056a17d5b3..7285d9a32f 100644 --- a/core/src/main/java/org/opensearch/sql/expression/function/SerializableQuadFunction.java +++ b/core/src/main/java/org/opensearch/sql/expression/function/SerializableQuadFunction.java @@ -3,7 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ - package org.opensearch.sql.expression.function; import java.io.Serializable; diff --git a/core/src/main/java/org/opensearch/sql/expression/function/SerializableTriFunction.java b/core/src/main/java/org/opensearch/sql/expression/function/SerializableTriFunction.java index 911012fcdb..e980b1c82a 100644 --- a/core/src/main/java/org/opensearch/sql/expression/function/SerializableTriFunction.java +++ b/core/src/main/java/org/opensearch/sql/expression/function/SerializableTriFunction.java @@ -3,7 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ - package org.opensearch.sql.expression.function; import java.io.Serializable; diff --git a/core/src/main/java/org/opensearch/sql/expression/function/TableFunctionImplementation.java b/core/src/main/java/org/opensearch/sql/expression/function/TableFunctionImplementation.java index f35ffe4898..b8b90bf5e3 100644 --- a/core/src/main/java/org/opensearch/sql/expression/function/TableFunctionImplementation.java +++ b/core/src/main/java/org/opensearch/sql/expression/function/TableFunctionImplementation.java @@ -9,11 +9,8 @@ import org.opensearch.sql.storage.Table; -/** - * Interface for table function which returns Table when executed. - */ +/** Interface for table function which returns Table when executed. */ public interface TableFunctionImplementation extends FunctionImplementation { Table applyArguments(); - } diff --git a/core/src/main/java/org/opensearch/sql/expression/operator/arthmetic/ArithmeticFunction.java b/core/src/main/java/org/opensearch/sql/expression/operator/arthmetic/ArithmeticFunction.java index 1f4ac3943c..3969b5310e 100644 --- a/core/src/main/java/org/opensearch/sql/expression/operator/arthmetic/ArithmeticFunction.java +++ b/core/src/main/java/org/opensearch/sql/expression/operator/arthmetic/ArithmeticFunction.java @@ -3,7 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ - package org.opensearch.sql.expression.operator.arthmetic; import static org.opensearch.sql.data.type.ExprCoreType.BYTE; @@ -30,12 +29,10 @@ import org.opensearch.sql.expression.function.FunctionName; /** - * The definition of arithmetic function - * add, Accepts two numbers and produces a number. - * subtract, Accepts two numbers and produces a number. - * multiply, Accepts two numbers and produces a number. - * divide, Accepts two numbers and produces a number. - * module, Accepts two numbers and produces a number. + * The definition of arithmetic function add, Accepts two numbers and produces a number. subtract, + * Accepts two numbers and produces a number. multiply, Accepts two numbers and produces a number. + * divide, Accepts two numbers and produces a number. module, Accepts two numbers and produces a + * number. */ @UtilityClass public class ArithmeticFunction { @@ -59,33 +56,47 @@ public static void register(BuiltinFunctionRepository repository) { } /** - * Definition of add(x, y) function. - * Returns the number x plus number y - * The supported signature of add function is - * (x: BYTE/SHORT/INTEGER/LONG/FLOAT/DOUBLE, y: BYTE/SHORT/INTEGER/LONG/FLOAT/DOUBLE) - * -> wider type between types of x and y + * Definition of add(x, y) function. Returns the number x plus number y The supported signature of + * add function is (x: BYTE/SHORT/INTEGER/LONG/FLOAT/DOUBLE, y: + * BYTE/SHORT/INTEGER/LONG/FLOAT/DOUBLE) -> wider type between types of x and y */ private static DefaultFunctionResolver addBase(FunctionName functionName) { - return define(functionName, - impl(nullMissingHandling( - (v1, v2) -> new ExprByteValue(v1.byteValue() + v2.byteValue())), - BYTE, BYTE, BYTE), - impl(nullMissingHandling( - (v1, v2) -> new ExprShortValue(v1.shortValue() + v2.shortValue())), - SHORT, SHORT, SHORT), - impl(nullMissingHandling( - (v1, v2) -> new ExprIntegerValue(Math.addExact(v1.integerValue(), v2.integerValue()))), - INTEGER, INTEGER, INTEGER), - impl(nullMissingHandling( - (v1, v2) -> new ExprLongValue(Math.addExact(v1.longValue(), v2.longValue()))), - LONG, LONG, LONG), - impl(nullMissingHandling( - (v1, v2) -> new ExprFloatValue(v1.floatValue() + v2.floatValue())), - FLOAT, FLOAT, FLOAT), - impl(nullMissingHandling( - (v1, v2) -> new ExprDoubleValue(v1.doubleValue() + v2.doubleValue())), - DOUBLE, DOUBLE, DOUBLE) - ); + return define( + functionName, + impl( + nullMissingHandling((v1, v2) -> new ExprByteValue(v1.byteValue() + v2.byteValue())), + BYTE, + BYTE, + BYTE), + impl( + nullMissingHandling((v1, v2) -> new ExprShortValue(v1.shortValue() + v2.shortValue())), + SHORT, + SHORT, + SHORT), + impl( + nullMissingHandling( + (v1, v2) -> + new ExprIntegerValue(Math.addExact(v1.integerValue(), v2.integerValue()))), + INTEGER, + INTEGER, + INTEGER), + impl( + nullMissingHandling( + (v1, v2) -> new ExprLongValue(Math.addExact(v1.longValue(), v2.longValue()))), + LONG, + LONG, + LONG), + impl( + nullMissingHandling((v1, v2) -> new ExprFloatValue(v1.floatValue() + v2.floatValue())), + FLOAT, + FLOAT, + FLOAT), + impl( + nullMissingHandling( + (v1, v2) -> new ExprDoubleValue(v1.doubleValue() + v2.doubleValue())), + DOUBLE, + DOUBLE, + DOUBLE)); } private static DefaultFunctionResolver add() { @@ -97,39 +108,67 @@ private static DefaultFunctionResolver addFunction() { } /** - * Definition of divide(x, y) function. - * Returns the number x divided by number y - * The supported signature of divide function is - * (x: BYTE/SHORT/INTEGER/LONG/FLOAT/DOUBLE, y: BYTE/SHORT/INTEGER/LONG/FLOAT/DOUBLE) - * -> wider type between types of x and y + * Definition of divide(x, y) function. Returns the number x divided by number y The supported + * signature of divide function is (x: BYTE/SHORT/INTEGER/LONG/FLOAT/DOUBLE, y: + * BYTE/SHORT/INTEGER/LONG/FLOAT/DOUBLE) -> wider type between types of x and y */ private static DefaultFunctionResolver divideBase(FunctionName functionName) { - return define(functionName, - impl(nullMissingHandling( - (v1, v2) -> v2.byteValue() == 0 ? ExprNullValue.of() : - new ExprByteValue(v1.byteValue() / v2.byteValue())), - BYTE, BYTE, BYTE), - impl(nullMissingHandling( - (v1, v2) -> v2.shortValue() == 0 ? ExprNullValue.of() : - new ExprShortValue(v1.shortValue() / v2.shortValue())), - SHORT, SHORT, SHORT), - impl(nullMissingHandling( - (v1, v2) -> v2.integerValue() == 0 ? ExprNullValue.of() : - new ExprIntegerValue(v1.integerValue() / v2.integerValue())), - INTEGER, INTEGER, INTEGER), - impl(nullMissingHandling( - (v1, v2) -> v2.longValue() == 0 ? ExprNullValue.of() : - new ExprLongValue(v1.longValue() / v2.longValue())), - LONG, LONG, LONG), - impl(nullMissingHandling( - (v1, v2) -> v2.floatValue() == 0 ? ExprNullValue.of() : - new ExprFloatValue(v1.floatValue() / v2.floatValue())), - FLOAT, FLOAT, FLOAT), - impl(nullMissingHandling( - (v1, v2) -> v2.doubleValue() == 0 ? ExprNullValue.of() : - new ExprDoubleValue(v1.doubleValue() / v2.doubleValue())), - DOUBLE, DOUBLE, DOUBLE) - ); + return define( + functionName, + impl( + nullMissingHandling( + (v1, v2) -> + v2.byteValue() == 0 + ? ExprNullValue.of() + : new ExprByteValue(v1.byteValue() / v2.byteValue())), + BYTE, + BYTE, + BYTE), + impl( + nullMissingHandling( + (v1, v2) -> + v2.shortValue() == 0 + ? ExprNullValue.of() + : new ExprShortValue(v1.shortValue() / v2.shortValue())), + SHORT, + SHORT, + SHORT), + impl( + nullMissingHandling( + (v1, v2) -> + v2.integerValue() == 0 + ? ExprNullValue.of() + : new ExprIntegerValue(v1.integerValue() / v2.integerValue())), + INTEGER, + INTEGER, + INTEGER), + impl( + nullMissingHandling( + (v1, v2) -> + v2.longValue() == 0 + ? ExprNullValue.of() + : new ExprLongValue(v1.longValue() / v2.longValue())), + LONG, + LONG, + LONG), + impl( + nullMissingHandling( + (v1, v2) -> + v2.floatValue() == 0 + ? ExprNullValue.of() + : new ExprFloatValue(v1.floatValue() / v2.floatValue())), + FLOAT, + FLOAT, + FLOAT), + impl( + nullMissingHandling( + (v1, v2) -> + v2.doubleValue() == 0 + ? ExprNullValue.of() + : new ExprDoubleValue(v1.doubleValue() / v2.doubleValue())), + DOUBLE, + DOUBLE, + DOUBLE)); } private static DefaultFunctionResolver divide() { @@ -141,39 +180,67 @@ private static DefaultFunctionResolver divideFunction() { } /** - * Definition of modulus(x, y) function. - * Returns the number x modulo by number y - * The supported signature of modulo function is - * (x: BYTE/SHORT/INTEGER/LONG/FLOAT/DOUBLE, y: BYTE/SHORT/INTEGER/LONG/FLOAT/DOUBLE) - * -> wider type between types of x and y + * Definition of modulus(x, y) function. Returns the number x modulo by number y The supported + * signature of modulo function is (x: BYTE/SHORT/INTEGER/LONG/FLOAT/DOUBLE, y: + * BYTE/SHORT/INTEGER/LONG/FLOAT/DOUBLE) -> wider type between types of x and y */ private static DefaultFunctionResolver modulusBase(FunctionName functionName) { - return define(functionName, - impl(nullMissingHandling( - (v1, v2) -> v2.byteValue() == 0 ? ExprNullValue.of() : - new ExprByteValue(v1.byteValue() % v2.byteValue())), - BYTE, BYTE, BYTE), - impl(nullMissingHandling( - (v1, v2) -> v2.shortValue() == 0 ? ExprNullValue.of() : - new ExprShortValue(v1.shortValue() % v2.shortValue())), - SHORT, SHORT, SHORT), - impl(nullMissingHandling( - (v1, v2) -> v2.integerValue() == 0 ? ExprNullValue.of() : - new ExprIntegerValue(v1.integerValue() % v2.integerValue())), - INTEGER, INTEGER, INTEGER), - impl(nullMissingHandling( - (v1, v2) -> v2.longValue() == 0 ? ExprNullValue.of() : - new ExprLongValue(v1.longValue() % v2.longValue())), - LONG, LONG, LONG), - impl(nullMissingHandling( - (v1, v2) -> v2.floatValue() == 0 ? ExprNullValue.of() : - new ExprFloatValue(v1.floatValue() % v2.floatValue())), - FLOAT, FLOAT, FLOAT), - impl(nullMissingHandling( - (v1, v2) -> v2.doubleValue() == 0 ? ExprNullValue.of() : - new ExprDoubleValue(v1.doubleValue() % v2.doubleValue())), - DOUBLE, DOUBLE, DOUBLE) - ); + return define( + functionName, + impl( + nullMissingHandling( + (v1, v2) -> + v2.byteValue() == 0 + ? ExprNullValue.of() + : new ExprByteValue(v1.byteValue() % v2.byteValue())), + BYTE, + BYTE, + BYTE), + impl( + nullMissingHandling( + (v1, v2) -> + v2.shortValue() == 0 + ? ExprNullValue.of() + : new ExprShortValue(v1.shortValue() % v2.shortValue())), + SHORT, + SHORT, + SHORT), + impl( + nullMissingHandling( + (v1, v2) -> + v2.integerValue() == 0 + ? ExprNullValue.of() + : new ExprIntegerValue(v1.integerValue() % v2.integerValue())), + INTEGER, + INTEGER, + INTEGER), + impl( + nullMissingHandling( + (v1, v2) -> + v2.longValue() == 0 + ? ExprNullValue.of() + : new ExprLongValue(v1.longValue() % v2.longValue())), + LONG, + LONG, + LONG), + impl( + nullMissingHandling( + (v1, v2) -> + v2.floatValue() == 0 + ? ExprNullValue.of() + : new ExprFloatValue(v1.floatValue() % v2.floatValue())), + FLOAT, + FLOAT, + FLOAT), + impl( + nullMissingHandling( + (v1, v2) -> + v2.doubleValue() == 0 + ? ExprNullValue.of() + : new ExprDoubleValue(v1.doubleValue() % v2.doubleValue())), + DOUBLE, + DOUBLE, + DOUBLE)); } private static DefaultFunctionResolver mod() { @@ -189,34 +256,47 @@ private static DefaultFunctionResolver modulusFunction() { } /** - * Definition of multiply(x, y) function. - * Returns the number x multiplied by number y - * The supported signature of multiply function is - * (x: BYTE/SHORT/INTEGER/LONG/FLOAT/DOUBLE, y: BYTE/SHORT/INTEGER/LONG/FLOAT/DOUBLE) - * -> wider type between types of x and y + * Definition of multiply(x, y) function. Returns the number x multiplied by number y The + * supported signature of multiply function is (x: BYTE/SHORT/INTEGER/LONG/FLOAT/DOUBLE, y: + * BYTE/SHORT/INTEGER/LONG/FLOAT/DOUBLE) -> wider type between types of x and y */ private static DefaultFunctionResolver multiplyBase(FunctionName functionName) { - return define(functionName, - impl(nullMissingHandling( - (v1, v2) -> new ExprByteValue(v1.byteValue() * v2.byteValue())), - BYTE, BYTE, BYTE), - impl(nullMissingHandling( - (v1, v2) -> new ExprShortValue(v1.shortValue() * v2.shortValue())), - SHORT, SHORT, SHORT), - impl(nullMissingHandling( - (v1, v2) -> new ExprIntegerValue(Math.multiplyExact(v1.integerValue(), - v2.integerValue()))), - INTEGER, INTEGER, INTEGER), - impl(nullMissingHandling( + return define( + functionName, + impl( + nullMissingHandling((v1, v2) -> new ExprByteValue(v1.byteValue() * v2.byteValue())), + BYTE, + BYTE, + BYTE), + impl( + nullMissingHandling((v1, v2) -> new ExprShortValue(v1.shortValue() * v2.shortValue())), + SHORT, + SHORT, + SHORT), + impl( + nullMissingHandling( + (v1, v2) -> + new ExprIntegerValue(Math.multiplyExact(v1.integerValue(), v2.integerValue()))), + INTEGER, + INTEGER, + INTEGER), + impl( + nullMissingHandling( (v1, v2) -> new ExprLongValue(Math.multiplyExact(v1.longValue(), v2.longValue()))), - LONG, LONG, LONG), - impl(nullMissingHandling( - (v1, v2) -> new ExprFloatValue(v1.floatValue() * v2.floatValue())), - FLOAT, FLOAT, FLOAT), - impl(nullMissingHandling( + LONG, + LONG, + LONG), + impl( + nullMissingHandling((v1, v2) -> new ExprFloatValue(v1.floatValue() * v2.floatValue())), + FLOAT, + FLOAT, + FLOAT), + impl( + nullMissingHandling( (v1, v2) -> new ExprDoubleValue(v1.doubleValue() * v2.doubleValue())), - DOUBLE, DOUBLE, DOUBLE) - ); + DOUBLE, + DOUBLE, + DOUBLE)); } private static DefaultFunctionResolver multiply() { @@ -228,34 +308,47 @@ private static DefaultFunctionResolver multiplyFunction() { } /** - * Definition of subtract(x, y) function. - * Returns the number x minus number y - * The supported signature of subtract function is - * (x: BYTE/SHORT/INTEGER/LONG/FLOAT/DOUBLE, y: BYTE/SHORT/INTEGER/LONG/FLOAT/DOUBLE) - * -> wider type between types of x and y + * Definition of subtract(x, y) function. Returns the number x minus number y The supported + * signature of subtract function is (x: BYTE/SHORT/INTEGER/LONG/FLOAT/DOUBLE, y: + * BYTE/SHORT/INTEGER/LONG/FLOAT/DOUBLE) -> wider type between types of x and y */ private static DefaultFunctionResolver subtractBase(FunctionName functionName) { - return define(functionName, - impl(nullMissingHandling( - (v1, v2) -> new ExprByteValue(v1.byteValue() - v2.byteValue())), - BYTE, BYTE, BYTE), - impl(nullMissingHandling( - (v1, v2) -> new ExprShortValue(v1.shortValue() - v2.shortValue())), - SHORT, SHORT, SHORT), - impl(nullMissingHandling( - (v1, v2) -> new ExprIntegerValue(Math.subtractExact(v1.integerValue(), - v2.integerValue()))), - INTEGER, INTEGER, INTEGER), - impl(nullMissingHandling( + return define( + functionName, + impl( + nullMissingHandling((v1, v2) -> new ExprByteValue(v1.byteValue() - v2.byteValue())), + BYTE, + BYTE, + BYTE), + impl( + nullMissingHandling((v1, v2) -> new ExprShortValue(v1.shortValue() - v2.shortValue())), + SHORT, + SHORT, + SHORT), + impl( + nullMissingHandling( + (v1, v2) -> + new ExprIntegerValue(Math.subtractExact(v1.integerValue(), v2.integerValue()))), + INTEGER, + INTEGER, + INTEGER), + impl( + nullMissingHandling( (v1, v2) -> new ExprLongValue(Math.subtractExact(v1.longValue(), v2.longValue()))), - LONG, LONG, LONG), - impl(nullMissingHandling( - (v1, v2) -> new ExprFloatValue(v1.floatValue() - v2.floatValue())), - FLOAT, FLOAT, FLOAT), - impl(nullMissingHandling( + LONG, + LONG, + LONG), + impl( + nullMissingHandling((v1, v2) -> new ExprFloatValue(v1.floatValue() - v2.floatValue())), + FLOAT, + FLOAT, + FLOAT), + impl( + nullMissingHandling( (v1, v2) -> new ExprDoubleValue(v1.doubleValue() - v2.doubleValue())), - DOUBLE, DOUBLE, DOUBLE) - ); + DOUBLE, + DOUBLE, + DOUBLE)); } private static DefaultFunctionResolver subtract() { @@ -265,4 +358,4 @@ private static DefaultFunctionResolver subtract() { private static DefaultFunctionResolver subtractFunction() { return subtractBase(BuiltinFunctionName.SUBTRACTFUNCTION.getName()); } -} \ No newline at end of file +} diff --git a/core/src/main/java/org/opensearch/sql/expression/operator/arthmetic/MathematicalFunction.java b/core/src/main/java/org/opensearch/sql/expression/operator/arthmetic/MathematicalFunction.java index 810d292ca2..21a348504e 100644 --- a/core/src/main/java/org/opensearch/sql/expression/operator/arthmetic/MathematicalFunction.java +++ b/core/src/main/java/org/opensearch/sql/expression/operator/arthmetic/MathematicalFunction.java @@ -3,7 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ - package org.opensearch.sql.expression.operator.arthmetic; import static org.opensearch.sql.data.type.ExprCoreType.BYTE; @@ -102,10 +101,14 @@ public static void register(BuiltinFunctionRepository repository) { * @return DefaultFunctionResolver for math functions. */ private static DefaultFunctionResolver baseMathFunction( - FunctionName functionName, SerializableFunction formula, ExprCoreType returnType) { - return define(functionName, ExprCoreType.numberTypes().stream().map(type -> - impl(nullMissingHandling(formula), returnType, type)).collect(Collectors.toList())); + FunctionName functionName, + SerializableFunction formula, + ExprCoreType returnType) { + return define( + functionName, + ExprCoreType.numberTypes().stream() + .map(type -> impl(nullMissingHandling(formula), returnType, type)) + .collect(Collectors.toList())); } /** @@ -113,20 +116,20 @@ private static DefaultFunctionResolver baseMathFunction( * LONG FLOAT -> FLOAT DOUBLE -> DOUBLE */ private static DefaultFunctionResolver abs() { - return define(BuiltinFunctionName.ABS.getName(), - impl(nullMissingHandling(v -> new ExprByteValue(Math.abs(v.byteValue()))), - BYTE, BYTE), - impl(nullMissingHandling(v -> new ExprShortValue(Math.abs(v.shortValue()))), - SHORT, SHORT), - impl(nullMissingHandling(v -> new ExprIntegerValue(Math.abs(v.integerValue()))), - INTEGER, INTEGER), - impl(nullMissingHandling(v -> new ExprLongValue(Math.abs(v.longValue()))), - LONG, LONG), - impl(nullMissingHandling(v -> new ExprFloatValue(Math.abs(v.floatValue()))), - FLOAT, FLOAT), - impl(nullMissingHandling(v -> new ExprDoubleValue(Math.abs(v.doubleValue()))), - DOUBLE, DOUBLE) - ); + return define( + BuiltinFunctionName.ABS.getName(), + impl(nullMissingHandling(v -> new ExprByteValue(Math.abs(v.byteValue()))), BYTE, BYTE), + impl(nullMissingHandling(v -> new ExprShortValue(Math.abs(v.shortValue()))), SHORT, SHORT), + impl( + nullMissingHandling(v -> new ExprIntegerValue(Math.abs(v.integerValue()))), + INTEGER, + INTEGER), + impl(nullMissingHandling(v -> new ExprLongValue(Math.abs(v.longValue()))), LONG, LONG), + impl(nullMissingHandling(v -> new ExprFloatValue(Math.abs(v.floatValue()))), FLOAT, FLOAT), + impl( + nullMissingHandling(v -> new ExprDoubleValue(Math.abs(v.doubleValue()))), + DOUBLE, + DOUBLE)); } /** @@ -134,83 +137,94 @@ private static DefaultFunctionResolver abs() { * to The supported signature of ceil/ceiling function is DOUBLE -> INTEGER */ private static DefaultFunctionResolver ceil() { - return define(BuiltinFunctionName.CEIL.getName(), - impl(nullMissingHandling(v -> new ExprLongValue(Math.ceil(v.doubleValue()))), - LONG, DOUBLE) - ); + return define( + BuiltinFunctionName.CEIL.getName(), + impl( + nullMissingHandling(v -> new ExprLongValue(Math.ceil(v.doubleValue()))), LONG, DOUBLE)); } private static DefaultFunctionResolver ceiling() { - return define(BuiltinFunctionName.CEILING.getName(), - impl(nullMissingHandling(v -> new ExprLongValue(Math.ceil(v.doubleValue()))), - LONG, DOUBLE) - ); + return define( + BuiltinFunctionName.CEILING.getName(), + impl( + nullMissingHandling(v -> new ExprLongValue(Math.ceil(v.doubleValue()))), LONG, DOUBLE)); } /** - * Definition of conv(x, a, b) function. - * Convert number x from base a to base b - * The supported signature of floor function is - * (STRING, INTEGER, INTEGER) -> STRING - * (INTEGER, INTEGER, INTEGER) -> STRING + * Definition of conv(x, a, b) function. Convert number x from base a to base b The supported + * signature of floor function is (STRING, INTEGER, INTEGER) -> STRING (INTEGER, INTEGER, INTEGER) + * -> STRING */ private static DefaultFunctionResolver conv() { - return define(BuiltinFunctionName.CONV.getName(), - impl(nullMissingHandling((x, a, b) -> new ExprStringValue( - Integer.toString(Integer.parseInt(x.stringValue(), a.integerValue()), - b.integerValue()))), - STRING, STRING, INTEGER, INTEGER), - impl(nullMissingHandling((x, a, b) -> new ExprStringValue( - Integer.toString(Integer.parseInt(x.integerValue().toString(), a.integerValue()), - b.integerValue()))), - STRING, INTEGER, INTEGER, INTEGER) - ); - } - - /** - * Definition of crc32(x) function. - * Calculate a cyclic redundancy check value and returns a 32-bit unsigned value - * The supported signature of crc32 function is - * STRING -> LONG + return define( + BuiltinFunctionName.CONV.getName(), + impl( + nullMissingHandling( + (x, a, b) -> + new ExprStringValue( + Integer.toString( + Integer.parseInt(x.stringValue(), a.integerValue()), + b.integerValue()))), + STRING, + STRING, + INTEGER, + INTEGER), + impl( + nullMissingHandling( + (x, a, b) -> + new ExprStringValue( + Integer.toString( + Integer.parseInt(x.integerValue().toString(), a.integerValue()), + b.integerValue()))), + STRING, + INTEGER, + INTEGER, + INTEGER)); + } + + /** + * Definition of crc32(x) function. Calculate a cyclic redundancy check value and returns a 32-bit + * unsigned value The supported signature of crc32 function is STRING -> LONG */ private static DefaultFunctionResolver crc32() { - return define(BuiltinFunctionName.CRC32.getName(), - impl(nullMissingHandling(v -> { - CRC32 crc = new CRC32(); - crc.update(v.stringValue().getBytes()); - return new ExprLongValue(crc.getValue()); - }), - LONG, STRING) - ); + return define( + BuiltinFunctionName.CRC32.getName(), + impl( + nullMissingHandling( + v -> { + CRC32 crc = new CRC32(); + crc.update(v.stringValue().getBytes()); + return new ExprLongValue(crc.getValue()); + }), + LONG, + STRING)); } - /** - * Definition of e() function. - * Get the Euler's number. - * () -> DOUBLE - */ + /** Definition of e() function. Get the Euler's number. () -> DOUBLE */ private static DefaultFunctionResolver euler() { - return define(BuiltinFunctionName.E.getName(), - impl(() -> new ExprDoubleValue(Math.E), DOUBLE) - ); + return define(BuiltinFunctionName.E.getName(), impl(() -> new ExprDoubleValue(Math.E), DOUBLE)); } /** - * Definition of exp(x) function. Calculate exponent function e to the x - * The supported signature of exp function is INTEGER/LONG/FLOAT/DOUBLE -> DOUBLE + * Definition of exp(x) function. Calculate exponent function e to the x The supported signature + * of exp function is INTEGER/LONG/FLOAT/DOUBLE -> DOUBLE */ private static DefaultFunctionResolver exp() { - return baseMathFunction(BuiltinFunctionName.EXP.getName(), - v -> new ExprDoubleValue(Math.exp(v.doubleValue())), DOUBLE); + return baseMathFunction( + BuiltinFunctionName.EXP.getName(), + v -> new ExprDoubleValue(Math.exp(v.doubleValue())), + DOUBLE); } /** - * Definition of expm1(x) function. Calculate exponent function e to the x, minus 1 - * The supported signature of exp function is INTEGER/LONG/FLOAT/DOUBLE -> DOUBLE + * Definition of expm1(x) function. Calculate exponent function e to the x, minus 1 The supported + * signature of exp function is INTEGER/LONG/FLOAT/DOUBLE -> DOUBLE */ private static DefaultFunctionResolver expm1() { - return baseMathFunction(BuiltinFunctionName.EXPM1.getName(), - v -> new ExprDoubleValue(Math.expm1(v.doubleValue())), DOUBLE); + return baseMathFunction( + BuiltinFunctionName.EXPM1.getName(), + v -> new ExprDoubleValue(Math.expm1(v.doubleValue())), + DOUBLE); } /** @@ -218,10 +232,12 @@ private static DefaultFunctionResolver expm1() { * The supported signature of floor function is DOUBLE -> INTEGER */ private static DefaultFunctionResolver floor() { - return define(BuiltinFunctionName.FLOOR.getName(), - impl(nullMissingHandling(v -> new ExprLongValue(Math.floor(v.doubleValue()))), - LONG, DOUBLE) - ); + return define( + BuiltinFunctionName.FLOOR.getName(), + impl( + nullMissingHandling(v -> new ExprLongValue(Math.floor(v.doubleValue()))), + LONG, + DOUBLE)); } /** @@ -229,9 +245,13 @@ private static DefaultFunctionResolver floor() { * ln function is INTEGER/LONG/FLOAT/DOUBLE -> DOUBLE */ private static DefaultFunctionResolver ln() { - return baseMathFunction(BuiltinFunctionName.LN.getName(), - v -> v.doubleValue() <= 0 ? ExprNullValue.of() : - new ExprDoubleValue(Math.log(v.doubleValue())), DOUBLE); + return baseMathFunction( + BuiltinFunctionName.LN.getName(), + v -> + v.doubleValue() <= 0 + ? ExprNullValue.of() + : new ExprDoubleValue(Math.log(v.doubleValue())), + DOUBLE); } /** @@ -240,37 +260,54 @@ private static DefaultFunctionResolver ln() { * INTEGER/LONG/FLOAT/DOUBLE]) -> DOUBLE */ private static DefaultFunctionResolver log() { - ImmutableList.Builder>> builder = new ImmutableList.Builder<>(); + ImmutableList.Builder< + SerializableFunction>> + builder = new ImmutableList.Builder<>(); // build unary log(x), SHORT/INTEGER/LONG/FLOAT/DOUBLE -> DOUBLE for (ExprType type : ExprCoreType.numberTypes()) { - builder.add(impl(nullMissingHandling(v -> v.doubleValue() <= 0 ? ExprNullValue.of() : - new ExprDoubleValue(Math.log(v.doubleValue()))), - DOUBLE, type)); + builder.add( + impl( + nullMissingHandling( + v -> + v.doubleValue() <= 0 + ? ExprNullValue.of() + : new ExprDoubleValue(Math.log(v.doubleValue()))), + DOUBLE, + type)); } // build binary function log(b, x) for (ExprType baseType : ExprCoreType.numberTypes()) { for (ExprType numberType : ExprCoreType.numberTypes()) { - builder.add(impl(nullMissingHandling((b, x) -> b.doubleValue() <= 0 || x.doubleValue() <= 0 - ? ExprNullValue.of() : new ExprDoubleValue( - Math.log(x.doubleValue()) / Math.log(b.doubleValue()))), - DOUBLE, baseType, numberType)); + builder.add( + impl( + nullMissingHandling( + (b, x) -> + b.doubleValue() <= 0 || x.doubleValue() <= 0 + ? ExprNullValue.of() + : new ExprDoubleValue( + Math.log(x.doubleValue()) / Math.log(b.doubleValue()))), + DOUBLE, + baseType, + numberType)); } } return define(BuiltinFunctionName.LOG.getName(), builder.build()); } - /** * Definition of log10(x) function. Calculate base-10 logarithm of x The supported signature of * log function is SHORT/INTEGER/LONG/FLOAT/DOUBLE -> DOUBLE */ private static DefaultFunctionResolver log10() { - return baseMathFunction(BuiltinFunctionName.LOG10.getName(), - v -> v.doubleValue() <= 0 ? ExprNullValue.of() : - new ExprDoubleValue(Math.log10(v.doubleValue())), DOUBLE); + return baseMathFunction( + BuiltinFunctionName.LOG10.getName(), + v -> + v.doubleValue() <= 0 + ? ExprNullValue.of() + : new ExprDoubleValue(Math.log10(v.doubleValue())), + DOUBLE); } /** @@ -278,60 +315,90 @@ private static DefaultFunctionResolver log10() { * function is SHORT/INTEGER/LONG/FLOAT/DOUBLE -> DOUBLE */ private static DefaultFunctionResolver log2() { - return baseMathFunction(BuiltinFunctionName.LOG2.getName(), - v -> v.doubleValue() <= 0 ? ExprNullValue.of() : - new ExprDoubleValue(Math.log(v.doubleValue()) / Math.log(2)), DOUBLE); + return baseMathFunction( + BuiltinFunctionName.LOG2.getName(), + v -> + v.doubleValue() <= 0 + ? ExprNullValue.of() + : new ExprDoubleValue(Math.log(v.doubleValue()) / Math.log(2)), + DOUBLE); } /** - * Definition of mod(x, y) function. - * Calculate the remainder of x divided by y - * The supported signature of mod function is - * (x: INTEGER/LONG/FLOAT/DOUBLE, y: INTEGER/LONG/FLOAT/DOUBLE) - * -> wider type between types of x and y + * Definition of mod(x, y) function. Calculate the remainder of x divided by y The supported + * signature of mod function is (x: INTEGER/LONG/FLOAT/DOUBLE, y: INTEGER/LONG/FLOAT/DOUBLE) -> + * wider type between types of x and y */ private static DefaultFunctionResolver mod() { - return define(BuiltinFunctionName.MOD.getName(), - impl(nullMissingHandling((v1, v2) -> v2.byteValue() == 0 ? ExprNullValue.of() : - new ExprByteValue(v1.byteValue() % v2.byteValue())), - BYTE, BYTE, BYTE), - impl(nullMissingHandling((v1, v2) -> v2.shortValue() == 0 ? ExprNullValue.of() : - new ExprShortValue(v1.shortValue() % v2.shortValue())), - SHORT, SHORT, SHORT), - impl(nullMissingHandling((v1, v2) -> v2.shortValue() == 0 ? ExprNullValue.of() : - new ExprIntegerValue(Math.floorMod(v1.integerValue(), v2.integerValue()))), - INTEGER, INTEGER, INTEGER), - impl(nullMissingHandling((v1, v2) -> v2.shortValue() == 0 ? ExprNullValue.of() : - new ExprLongValue(Math.floorMod(v1.longValue(), v2.longValue()))), - LONG, LONG, LONG), - impl(nullMissingHandling((v1, v2) -> v2.shortValue() == 0 ? ExprNullValue.of() : - new ExprFloatValue(v1.floatValue() % v2.floatValue())), - FLOAT, FLOAT, FLOAT), - impl(nullMissingHandling((v1, v2) -> v2.shortValue() == 0 ? ExprNullValue.of() : - new ExprDoubleValue(v1.doubleValue() % v2.doubleValue())), - DOUBLE, DOUBLE, DOUBLE) - ); - } - - /** - * Definition of pi() function. - * Get the value of pi. - * () -> DOUBLE - */ + return define( + BuiltinFunctionName.MOD.getName(), + impl( + nullMissingHandling( + (v1, v2) -> + v2.byteValue() == 0 + ? ExprNullValue.of() + : new ExprByteValue(v1.byteValue() % v2.byteValue())), + BYTE, + BYTE, + BYTE), + impl( + nullMissingHandling( + (v1, v2) -> + v2.shortValue() == 0 + ? ExprNullValue.of() + : new ExprShortValue(v1.shortValue() % v2.shortValue())), + SHORT, + SHORT, + SHORT), + impl( + nullMissingHandling( + (v1, v2) -> + v2.shortValue() == 0 + ? ExprNullValue.of() + : new ExprIntegerValue( + Math.floorMod(v1.integerValue(), v2.integerValue()))), + INTEGER, + INTEGER, + INTEGER), + impl( + nullMissingHandling( + (v1, v2) -> + v2.shortValue() == 0 + ? ExprNullValue.of() + : new ExprLongValue(Math.floorMod(v1.longValue(), v2.longValue()))), + LONG, + LONG, + LONG), + impl( + nullMissingHandling( + (v1, v2) -> + v2.shortValue() == 0 + ? ExprNullValue.of() + : new ExprFloatValue(v1.floatValue() % v2.floatValue())), + FLOAT, + FLOAT, + FLOAT), + impl( + nullMissingHandling( + (v1, v2) -> + v2.shortValue() == 0 + ? ExprNullValue.of() + : new ExprDoubleValue(v1.doubleValue() % v2.doubleValue())), + DOUBLE, + DOUBLE, + DOUBLE)); + } + + /** Definition of pi() function. Get the value of pi. () -> DOUBLE */ private static DefaultFunctionResolver pi() { - return define(BuiltinFunctionName.PI.getName(), - impl(() -> new ExprDoubleValue(Math.PI), DOUBLE) - ); + return define( + BuiltinFunctionName.PI.getName(), impl(() -> new ExprDoubleValue(Math.PI), DOUBLE)); } /** - * Definition of pow(x, y)/power(x, y) function. - * Calculate the value of x raised to the power of y - * The supported signature of pow/power function is - * (INTEGER, INTEGER) -> DOUBLE - * (LONG, LONG) -> DOUBLE - * (FLOAT, FLOAT) -> DOUBLE - * (DOUBLE, DOUBLE) -> DOUBLE + * Definition of pow(x, y)/power(x, y) function. Calculate the value of x raised to the power of y + * The supported signature of pow/power function is (INTEGER, INTEGER) -> DOUBLE (LONG, LONG) -> + * DOUBLE (FLOAT, FLOAT) -> DOUBLE (DOUBLE, DOUBLE) -> DOUBLE */ private static DefaultFunctionResolver pow() { return define(BuiltinFunctionName.POW.getName(), powerFunctionImpl()); @@ -341,336 +408,445 @@ private static DefaultFunctionResolver power() { return define(BuiltinFunctionName.POWER.getName(), powerFunctionImpl()); } - private List>> powerFunctionImpl() { + private List>> + powerFunctionImpl() { return Arrays.asList( - impl(nullMissingHandling( - (v1, v2) -> new ExprDoubleValue(Math.pow(v1.shortValue(), v2.shortValue()))), - DOUBLE, SHORT, SHORT), - impl(nullMissingHandling( - (v1, v2) -> new ExprDoubleValue(Math.pow(v1.integerValue(), v2.integerValue()))), - DOUBLE, INTEGER, INTEGER), - impl(nullMissingHandling( - (v1, v2) -> new ExprDoubleValue(Math.pow(v1.longValue(), v2.longValue()))), - DOUBLE, LONG, LONG), - impl(nullMissingHandling( - (v1, v2) -> v1.floatValue() <= 0 && v2.floatValue() != Math.floor(v2.floatValue()) - ? ExprNullValue.of() : - new ExprDoubleValue(Math.pow(v1.floatValue(), v2.floatValue()))), - DOUBLE, FLOAT, FLOAT), - impl(nullMissingHandling( - (v1, v2) -> v1.doubleValue() <= 0 && v2.doubleValue() != Math.floor(v2.doubleValue()) - ? ExprNullValue.of() : - new ExprDoubleValue(Math.pow(v1.doubleValue(), v2.doubleValue()))), - DOUBLE, DOUBLE, DOUBLE)); - } - - /** - * Definition of rand() and rand(N) function. - * rand() returns a random floating-point value in the range 0 <= value < 1.0 - * If integer N is specified, the seed is initialized prior to execution. + impl( + nullMissingHandling( + (v1, v2) -> new ExprDoubleValue(Math.pow(v1.shortValue(), v2.shortValue()))), + DOUBLE, + SHORT, + SHORT), + impl( + nullMissingHandling( + (v1, v2) -> new ExprDoubleValue(Math.pow(v1.integerValue(), v2.integerValue()))), + DOUBLE, + INTEGER, + INTEGER), + impl( + nullMissingHandling( + (v1, v2) -> new ExprDoubleValue(Math.pow(v1.longValue(), v2.longValue()))), + DOUBLE, + LONG, + LONG), + impl( + nullMissingHandling( + (v1, v2) -> + v1.floatValue() <= 0 && v2.floatValue() != Math.floor(v2.floatValue()) + ? ExprNullValue.of() + : new ExprDoubleValue(Math.pow(v1.floatValue(), v2.floatValue()))), + DOUBLE, + FLOAT, + FLOAT), + impl( + nullMissingHandling( + (v1, v2) -> + v1.doubleValue() <= 0 && v2.doubleValue() != Math.floor(v2.doubleValue()) + ? ExprNullValue.of() + : new ExprDoubleValue(Math.pow(v1.doubleValue(), v2.doubleValue()))), + DOUBLE, + DOUBLE, + DOUBLE)); + } + + /** + * Definition of rand() and rand(N) function. rand() returns a random floating-point value in the + * range 0 <= value < 1.0 If integer N is specified, the seed is initialized prior to execution. * One implication of this behavior is with identical argument N,rand(N) returns the same value - * each time, and thus produces a repeatable sequence of column values. - * The supported signature of rand function is - * ([INTEGER]) -> FLOAT + * each time, and thus produces a repeatable sequence of column values. The supported signature of + * rand function is ([INTEGER]) -> FLOAT */ private static DefaultFunctionResolver rand() { - return define(BuiltinFunctionName.RAND.getName(), + return define( + BuiltinFunctionName.RAND.getName(), impl(() -> new ExprFloatValue(new Random().nextFloat()), FLOAT), - impl(nullMissingHandling( - v -> new ExprFloatValue(new Random(v.integerValue()).nextFloat())), FLOAT, INTEGER) - ); + impl( + nullMissingHandling(v -> new ExprFloatValue(new Random(v.integerValue()).nextFloat())), + FLOAT, + INTEGER)); } /** - * Definition of rint(x) function. - * Returns the closest whole integer value to x - * The supported signature is - * BYTE/SHORT/INTEGER/LONG/FLOAT/DOUBLE -> DOUBLE + * Definition of rint(x) function. Returns the closest whole integer value to x The supported + * signature is BYTE/SHORT/INTEGER/LONG/FLOAT/DOUBLE -> DOUBLE */ private static DefaultFunctionResolver rint() { - return baseMathFunction(BuiltinFunctionName.RINT.getName(), - v -> new ExprDoubleValue(Math.rint(v.doubleValue())), DOUBLE); + return baseMathFunction( + BuiltinFunctionName.RINT.getName(), + v -> new ExprDoubleValue(Math.rint(v.doubleValue())), + DOUBLE); } /** - * Definition of round(x)/round(x, d) function. - * Rounds the argument x to d decimal places, d defaults to 0 if not specified. - * The supported signature of round function is - * (x: INTEGER [, y: INTEGER]) -> INTEGER - * (x: LONG [, y: INTEGER]) -> LONG - * (x: FLOAT [, y: INTEGER]) -> FLOAT - * (x: DOUBLE [, y: INTEGER]) -> DOUBLE + * Definition of round(x)/round(x, d) function. Rounds the argument x to d decimal places, d + * defaults to 0 if not specified. The supported signature of round function is (x: INTEGER [, y: + * INTEGER]) -> INTEGER (x: LONG [, y: INTEGER]) -> LONG (x: FLOAT [, y: INTEGER]) -> FLOAT (x: + * DOUBLE [, y: INTEGER]) -> DOUBLE */ private static DefaultFunctionResolver round() { - return define(BuiltinFunctionName.ROUND.getName(), + return define( + BuiltinFunctionName.ROUND.getName(), // rand(x) - impl(nullMissingHandling(v -> new ExprLongValue((long) Math.round(v.integerValue()))), - LONG, INTEGER), - impl(nullMissingHandling(v -> new ExprLongValue((long) Math.round(v.longValue()))), - LONG, LONG), - impl(nullMissingHandling(v -> new ExprDoubleValue((double) Math.round(v.floatValue()))), - DOUBLE, FLOAT), - impl(nullMissingHandling(v -> new ExprDoubleValue(new BigDecimal(v.doubleValue()) - .setScale(0, RoundingMode.HALF_UP).doubleValue())), - DOUBLE, DOUBLE), + impl( + nullMissingHandling(v -> new ExprLongValue((long) Math.round(v.integerValue()))), + LONG, + INTEGER), + impl( + nullMissingHandling(v -> new ExprLongValue((long) Math.round(v.longValue()))), + LONG, + LONG), + impl( + nullMissingHandling(v -> new ExprDoubleValue((double) Math.round(v.floatValue()))), + DOUBLE, + FLOAT), + impl( + nullMissingHandling( + v -> + new ExprDoubleValue( + new BigDecimal(v.doubleValue()) + .setScale(0, RoundingMode.HALF_UP) + .doubleValue())), + DOUBLE, + DOUBLE), // rand(x, d) - impl(nullMissingHandling((x, d) -> new ExprLongValue(new BigDecimal(x.integerValue()) - .setScale(d.integerValue(), RoundingMode.HALF_UP).longValue())), - LONG, INTEGER, INTEGER), - impl(nullMissingHandling((x, d) -> new ExprLongValue(new BigDecimal(x.longValue()) - .setScale(d.integerValue(), RoundingMode.HALF_UP).longValue())), - LONG, LONG, INTEGER), - impl(nullMissingHandling((x, d) -> new ExprDoubleValue(new BigDecimal(x.floatValue()) - .setScale(d.integerValue(), RoundingMode.HALF_UP).doubleValue())), - DOUBLE, FLOAT, INTEGER), - impl(nullMissingHandling((x, d) -> new ExprDoubleValue(new BigDecimal(x.doubleValue()) - .setScale(d.integerValue(), RoundingMode.HALF_UP).doubleValue())), - DOUBLE, DOUBLE, INTEGER)); - } - - /** - * Definition of sign(x) function. - * Returns the sign of the argument as -1, 0, or 1 - * depending on whether x is negative, zero, or positive - * The supported signature is + impl( + nullMissingHandling( + (x, d) -> + new ExprLongValue( + new BigDecimal(x.integerValue()) + .setScale(d.integerValue(), RoundingMode.HALF_UP) + .longValue())), + LONG, + INTEGER, + INTEGER), + impl( + nullMissingHandling( + (x, d) -> + new ExprLongValue( + new BigDecimal(x.longValue()) + .setScale(d.integerValue(), RoundingMode.HALF_UP) + .longValue())), + LONG, + LONG, + INTEGER), + impl( + nullMissingHandling( + (x, d) -> + new ExprDoubleValue( + new BigDecimal(x.floatValue()) + .setScale(d.integerValue(), RoundingMode.HALF_UP) + .doubleValue())), + DOUBLE, + FLOAT, + INTEGER), + impl( + nullMissingHandling( + (x, d) -> + new ExprDoubleValue( + new BigDecimal(x.doubleValue()) + .setScale(d.integerValue(), RoundingMode.HALF_UP) + .doubleValue())), + DOUBLE, + DOUBLE, + INTEGER)); + } + + /** + * Definition of sign(x) function. Returns the sign of the argument as -1, 0, or 1 depending on + * whether x is negative, zero, or positive The supported signature is * SHORT/INTEGER/LONG/FLOAT/DOUBLE -> INTEGER */ private static DefaultFunctionResolver sign() { - return baseMathFunction(BuiltinFunctionName.SIGN.getName(), - v -> new ExprIntegerValue(Math.signum(v.doubleValue())), INTEGER); + return baseMathFunction( + BuiltinFunctionName.SIGN.getName(), + v -> new ExprIntegerValue(Math.signum(v.doubleValue())), + INTEGER); } /** - * Definition of signum(x) function. - * Returns the sign of the argument as -1.0, 0, or 1.0 - * depending on whether x is negative, zero, or positive - * The supported signature is + * Definition of signum(x) function. Returns the sign of the argument as -1.0, 0, or 1.0 depending + * on whether x is negative, zero, or positive The supported signature is * BYTE/SHORT/INTEGER/LONG/FLOAT/DOUBLE -> INTEGER */ private static DefaultFunctionResolver signum() { - return baseMathFunction(BuiltinFunctionName.SIGNUM.getName(), - v -> new ExprIntegerValue(Math.signum(v.doubleValue())), INTEGER); + return baseMathFunction( + BuiltinFunctionName.SIGNUM.getName(), + v -> new ExprIntegerValue(Math.signum(v.doubleValue())), + INTEGER); } /** - * Definition of sinh(x) function. - * Returns the hyperbolix sine of x, defined as (((e^x) - (e^(-x))) / 2) - * The supported signature is - * BYTE/SHORT/INTEGER/LONG/FLOAT/DOUBLE -> DOUBLE + * Definition of sinh(x) function. Returns the hyperbolix sine of x, defined as (((e^x) - + * (e^(-x))) / 2) The supported signature is BYTE/SHORT/INTEGER/LONG/FLOAT/DOUBLE -> DOUBLE */ private static DefaultFunctionResolver sinh() { - return baseMathFunction(BuiltinFunctionName.SINH.getName(), - v -> new ExprDoubleValue(Math.sinh(v.doubleValue())), DOUBLE); + return baseMathFunction( + BuiltinFunctionName.SINH.getName(), + v -> new ExprDoubleValue(Math.sinh(v.doubleValue())), + DOUBLE); } /** - * Definition of sqrt(x) function. - * Calculate the square root of a non-negative number x - * The supported signature is - * INTEGER/LONG/FLOAT/DOUBLE -> DOUBLE + * Definition of sqrt(x) function. Calculate the square root of a non-negative number x The + * supported signature is INTEGER/LONG/FLOAT/DOUBLE -> DOUBLE */ private static DefaultFunctionResolver sqrt() { - return baseMathFunction(BuiltinFunctionName.SQRT.getName(), - v -> v.doubleValue() < 0 ? ExprNullValue.of() : - new ExprDoubleValue(Math.sqrt(v.doubleValue())), DOUBLE); + return baseMathFunction( + BuiltinFunctionName.SQRT.getName(), + v -> + v.doubleValue() < 0 + ? ExprNullValue.of() + : new ExprDoubleValue(Math.sqrt(v.doubleValue())), + DOUBLE); } /** - * Definition of cbrt(x) function. - * Calculate the cube root of a number x - * The supported signature is - * INTEGER/LONG/FLOAT/DOUBLE -> DOUBLE + * Definition of cbrt(x) function. Calculate the cube root of a number x The supported signature + * is INTEGER/LONG/FLOAT/DOUBLE -> DOUBLE */ private static DefaultFunctionResolver cbrt() { - return baseMathFunction(BuiltinFunctionName.CBRT.getName(), - v -> new ExprDoubleValue(Math.cbrt(v.doubleValue())), DOUBLE); + return baseMathFunction( + BuiltinFunctionName.CBRT.getName(), + v -> new ExprDoubleValue(Math.cbrt(v.doubleValue())), + DOUBLE); } /** - * Definition of truncate(x, d) function. - * Returns the number x, truncated to d decimal places - * The supported signature of round function is - * (x: INTEGER, y: INTEGER) -> LONG - * (x: LONG, y: INTEGER) -> LONG - * (x: FLOAT, y: INTEGER) -> DOUBLE - * (x: DOUBLE, y: INTEGER) -> DOUBLE + * Definition of truncate(x, d) function. Returns the number x, truncated to d decimal places The + * supported signature of round function is (x: INTEGER, y: INTEGER) -> LONG (x: LONG, y: INTEGER) + * -> LONG (x: FLOAT, y: INTEGER) -> DOUBLE (x: DOUBLE, y: INTEGER) -> DOUBLE */ private static DefaultFunctionResolver truncate() { - return define(BuiltinFunctionName.TRUNCATE.getName(), - impl(nullMissingHandling((x, y) -> new ExprLongValue(BigDecimal.valueOf(x.integerValue()) - .setScale(y.integerValue(), RoundingMode.DOWN).longValue())), - LONG, INTEGER, INTEGER), - impl(nullMissingHandling((x, y) -> new ExprLongValue(BigDecimal.valueOf(x.longValue()) - .setScale(y.integerValue(), RoundingMode.DOWN).longValue())), - LONG, LONG, INTEGER), - impl(nullMissingHandling((x, y) -> new ExprDoubleValue(BigDecimal.valueOf(x.floatValue()) - .setScale(y.integerValue(), RoundingMode.DOWN).doubleValue())), - DOUBLE, FLOAT, INTEGER), - impl(nullMissingHandling((x, y) -> new ExprDoubleValue(BigDecimal.valueOf(x.doubleValue()) - .setScale(y.integerValue(), RoundingMode.DOWN).doubleValue())), - DOUBLE, DOUBLE, INTEGER)); - } - - /** - * Definition of acos(x) function. - * Calculates the arc cosine of x, that is, the value whose cosine is x. - * Returns NULL if x is not in the range -1 to 1. - * The supported signature of acos function is - * INTEGER/LONG/FLOAT/DOUBLE -> DOUBLE + return define( + BuiltinFunctionName.TRUNCATE.getName(), + impl( + nullMissingHandling( + (x, y) -> + new ExprLongValue( + BigDecimal.valueOf(x.integerValue()) + .setScale(y.integerValue(), RoundingMode.DOWN) + .longValue())), + LONG, + INTEGER, + INTEGER), + impl( + nullMissingHandling( + (x, y) -> + new ExprLongValue( + BigDecimal.valueOf(x.longValue()) + .setScale(y.integerValue(), RoundingMode.DOWN) + .longValue())), + LONG, + LONG, + INTEGER), + impl( + nullMissingHandling( + (x, y) -> + new ExprDoubleValue( + BigDecimal.valueOf(x.floatValue()) + .setScale(y.integerValue(), RoundingMode.DOWN) + .doubleValue())), + DOUBLE, + FLOAT, + INTEGER), + impl( + nullMissingHandling( + (x, y) -> + new ExprDoubleValue( + BigDecimal.valueOf(x.doubleValue()) + .setScale(y.integerValue(), RoundingMode.DOWN) + .doubleValue())), + DOUBLE, + DOUBLE, + INTEGER)); + } + + /** + * Definition of acos(x) function. Calculates the arc cosine of x, that is, the value whose cosine + * is x. Returns NULL if x is not in the range -1 to 1. The supported signature of acos function + * is INTEGER/LONG/FLOAT/DOUBLE -> DOUBLE */ private static DefaultFunctionResolver acos() { - return define(BuiltinFunctionName.ACOS.getName(), + return define( + BuiltinFunctionName.ACOS.getName(), ExprCoreType.numberTypes().stream() - .map(type -> impl(nullMissingHandling( - v -> v.doubleValue() < -1 || v.doubleValue() > 1 ? ExprNullValue.of() : - new ExprDoubleValue(Math.acos(v.doubleValue()))), - DOUBLE, type)).collect(Collectors.toList())); - } - - /** - * Definition of asin(x) function. - * Calculates the arc sine of x, that is, the value whose sine is x. - * Returns NULL if x is not in the range -1 to 1. - * The supported signature of asin function is + .map( + type -> + impl( + nullMissingHandling( + v -> + v.doubleValue() < -1 || v.doubleValue() > 1 + ? ExprNullValue.of() + : new ExprDoubleValue(Math.acos(v.doubleValue()))), + DOUBLE, + type)) + .collect(Collectors.toList())); + } + + /** + * Definition of asin(x) function. Calculates the arc sine of x, that is, the value whose sine is + * x. Returns NULL if x is not in the range -1 to 1. The supported signature of asin function is * INTEGER/LONG/FLOAT/DOUBLE -> DOUBLE */ private static DefaultFunctionResolver asin() { - return define(BuiltinFunctionName.ASIN.getName(), + return define( + BuiltinFunctionName.ASIN.getName(), ExprCoreType.numberTypes().stream() - .map(type -> impl(nullMissingHandling( - v -> v.doubleValue() < -1 || v.doubleValue() > 1 ? ExprNullValue.of() : - new ExprDoubleValue(Math.asin(v.doubleValue()))), - DOUBLE, type)).collect(Collectors.toList())); - } - - /** - * Definition of atan(x) and atan(y, x) function. - * atan(x) calculates the arc tangent of x, that is, the value whose tangent is x. - * atan(y, x) calculates the arc tangent of y / x, except that the signs of both arguments - * are used to determine the quadrant of the result. - * The supported signature of atan function is - * (x: INTEGER/LONG/FLOAT/DOUBLE, y: INTEGER/LONG/FLOAT/DOUBLE) -> DOUBLE + .map( + type -> + impl( + nullMissingHandling( + v -> + v.doubleValue() < -1 || v.doubleValue() > 1 + ? ExprNullValue.of() + : new ExprDoubleValue(Math.asin(v.doubleValue()))), + DOUBLE, + type)) + .collect(Collectors.toList())); + } + + /** + * Definition of atan(x) and atan(y, x) function. atan(x) calculates the arc tangent of x, that + * is, the value whose tangent is x. atan(y, x) calculates the arc tangent of y / x, except that + * the signs of both arguments are used to determine the quadrant of the result. The supported + * signature of atan function is (x: INTEGER/LONG/FLOAT/DOUBLE, y: INTEGER/LONG/FLOAT/DOUBLE) -> + * DOUBLE */ private static DefaultFunctionResolver atan() { - ImmutableList.Builder>> builder = new ImmutableList.Builder<>(); + ImmutableList.Builder< + SerializableFunction>> + builder = new ImmutableList.Builder<>(); for (ExprType type : ExprCoreType.numberTypes()) { - builder.add(impl(nullMissingHandling(x -> new ExprDoubleValue(Math.atan(x.doubleValue()))), - type, DOUBLE)); - builder.add(impl(nullMissingHandling((y, x) -> new ExprDoubleValue(Math.atan2(y.doubleValue(), - x.doubleValue()))), - DOUBLE, type, type)); + builder.add( + impl( + nullMissingHandling(x -> new ExprDoubleValue(Math.atan(x.doubleValue()))), + type, + DOUBLE)); + builder.add( + impl( + nullMissingHandling( + (y, x) -> new ExprDoubleValue(Math.atan2(y.doubleValue(), x.doubleValue()))), + DOUBLE, + type, + type)); } return define(BuiltinFunctionName.ATAN.getName(), builder.build()); } /** - * Definition of atan2(y, x) function. - * Calculates the arc tangent of y / x, except that the signs of both arguments - * are used to determine the quadrant of the result. - * The supported signature of atan2 function is - * (x: INTEGER/LONG/FLOAT/DOUBLE, y: INTEGER/LONG/FLOAT/DOUBLE) -> DOUBLE + * Definition of atan2(y, x) function. Calculates the arc tangent of y / x, except that the signs + * of both arguments are used to determine the quadrant of the result. The supported signature of + * atan2 function is (x: INTEGER/LONG/FLOAT/DOUBLE, y: INTEGER/LONG/FLOAT/DOUBLE) -> DOUBLE */ private static DefaultFunctionResolver atan2() { - ImmutableList.Builder>> builder = new ImmutableList.Builder<>(); + ImmutableList.Builder< + SerializableFunction>> + builder = new ImmutableList.Builder<>(); for (ExprType type : ExprCoreType.numberTypes()) { - builder.add(impl(nullMissingHandling((y, x) -> new ExprDoubleValue(Math.atan2(y.doubleValue(), - x.doubleValue()))), DOUBLE, type, type)); + builder.add( + impl( + nullMissingHandling( + (y, x) -> new ExprDoubleValue(Math.atan2(y.doubleValue(), x.doubleValue()))), + DOUBLE, + type, + type)); } return define(BuiltinFunctionName.ATAN2.getName(), builder.build()); } /** - * Definition of cos(x) function. - * Calculates the cosine of X, where X is given in radians - * The supported signature of cos function is - * INTEGER/LONG/FLOAT/DOUBLE -> DOUBLE + * Definition of cos(x) function. Calculates the cosine of X, where X is given in radians The + * supported signature of cos function is INTEGER/LONG/FLOAT/DOUBLE -> DOUBLE */ private static DefaultFunctionResolver cos() { - return baseMathFunction(BuiltinFunctionName.COS.getName(), - v -> new ExprDoubleValue(Math.cos(v.doubleValue())), DOUBLE); + return baseMathFunction( + BuiltinFunctionName.COS.getName(), + v -> new ExprDoubleValue(Math.cos(v.doubleValue())), + DOUBLE); } /** - * Definition of cosh(x) function. - * Returns the hyperbolic cosine of x, defined as (((e^x) + (e^(-x))) / 2) - * The supported signature is - * BYTE/SHORT/INTEGER/LONG/FLOAT/DOUBLE -> DOUBLE + * Definition of cosh(x) function. Returns the hyperbolic cosine of x, defined as (((e^x) + + * (e^(-x))) / 2) The supported signature is BYTE/SHORT/INTEGER/LONG/FLOAT/DOUBLE -> DOUBLE */ private static DefaultFunctionResolver cosh() { - return baseMathFunction(BuiltinFunctionName.COSH.getName(), - v -> new ExprDoubleValue(Math.cosh(v.doubleValue())), DOUBLE); + return baseMathFunction( + BuiltinFunctionName.COSH.getName(), + v -> new ExprDoubleValue(Math.cosh(v.doubleValue())), + DOUBLE); } /** - * Definition of cot(x) function. - * Calculates the cotangent of x - * The supported signature of cot function is - * INTEGER/LONG/FLOAT/DOUBLE -> DOUBLE + * Definition of cot(x) function. Calculates the cotangent of x The supported signature of cot + * function is INTEGER/LONG/FLOAT/DOUBLE -> DOUBLE */ private static DefaultFunctionResolver cot() { - return define(BuiltinFunctionName.COT.getName(), + return define( + BuiltinFunctionName.COT.getName(), ExprCoreType.numberTypes().stream() - .map(type -> impl(nullMissingHandling( - v -> { - Double value = v.doubleValue(); - if (value == 0) { - throw new ArithmeticException( - String.format("Out of range value for cot(%s)", value)); - } - return new ExprDoubleValue(1 / Math.tan(value)); - }), - DOUBLE, type)).collect(Collectors.toList())); - } - - /** - * Definition of degrees(x) function. - * Converts x from radians to degrees - * The supported signature of degrees function is - * INTEGER/LONG/FLOAT/DOUBLE -> DOUBLE + .map( + type -> + impl( + nullMissingHandling( + v -> { + Double value = v.doubleValue(); + if (value == 0) { + throw new ArithmeticException( + String.format("Out of range value for cot(%s)", value)); + } + return new ExprDoubleValue(1 / Math.tan(value)); + }), + DOUBLE, + type)) + .collect(Collectors.toList())); + } + + /** + * Definition of degrees(x) function. Converts x from radians to degrees The supported signature + * of degrees function is INTEGER/LONG/FLOAT/DOUBLE -> DOUBLE */ private static DefaultFunctionResolver degrees() { - return baseMathFunction(BuiltinFunctionName.DEGREES.getName(), - v -> new ExprDoubleValue(Math.toDegrees(v.doubleValue())), DOUBLE); + return baseMathFunction( + BuiltinFunctionName.DEGREES.getName(), + v -> new ExprDoubleValue(Math.toDegrees(v.doubleValue())), + DOUBLE); } /** - * Definition of radians(x) function. - * Converts x from degrees to radians - * The supported signature of radians function is - * INTEGER/LONG/FLOAT/DOUBLE -> DOUBLE + * Definition of radians(x) function. Converts x from degrees to radians The supported signature + * of radians function is INTEGER/LONG/FLOAT/DOUBLE -> DOUBLE */ private static DefaultFunctionResolver radians() { - return baseMathFunction(BuiltinFunctionName.RADIANS.getName(), - v -> new ExprDoubleValue(Math.toRadians(v.doubleValue())), DOUBLE); + return baseMathFunction( + BuiltinFunctionName.RADIANS.getName(), + v -> new ExprDoubleValue(Math.toRadians(v.doubleValue())), + DOUBLE); } /** - * Definition of sin(x) function. - * Calculates the sine of x, where x is given in radians - * The supported signature of sin function is - * INTEGER/LONG/FLOAT/DOUBLE -> DOUBLE + * Definition of sin(x) function. Calculates the sine of x, where x is given in radians The + * supported signature of sin function is INTEGER/LONG/FLOAT/DOUBLE -> DOUBLE */ private static DefaultFunctionResolver sin() { - return baseMathFunction(BuiltinFunctionName.SIN.getName(), - v -> new ExprDoubleValue(Math.sin(v.doubleValue())), DOUBLE); + return baseMathFunction( + BuiltinFunctionName.SIN.getName(), + v -> new ExprDoubleValue(Math.sin(v.doubleValue())), + DOUBLE); } /** - * Definition of tan(x) function. - * Calculates the tangent of x, where x is given in radians - * The supported signature of tan function is - * INTEGER/LONG/FLOAT/DOUBLE -> DOUBLE + * Definition of tan(x) function. Calculates the tangent of x, where x is given in radians The + * supported signature of tan function is INTEGER/LONG/FLOAT/DOUBLE -> DOUBLE */ private static DefaultFunctionResolver tan() { - return baseMathFunction(BuiltinFunctionName.TAN.getName(), - v -> new ExprDoubleValue(Math.tan(v.doubleValue())), DOUBLE); + return baseMathFunction( + BuiltinFunctionName.TAN.getName(), + v -> new ExprDoubleValue(Math.tan(v.doubleValue())), + DOUBLE); } } diff --git a/core/src/main/java/org/opensearch/sql/expression/operator/convert/TypeCastOperator.java b/core/src/main/java/org/opensearch/sql/expression/operator/convert/TypeCastOperator.java index d3295a53f0..7c3565f69c 100644 --- a/core/src/main/java/org/opensearch/sql/expression/operator/convert/TypeCastOperator.java +++ b/core/src/main/java/org/opensearch/sql/expression/operator/convert/TypeCastOperator.java @@ -3,7 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ - package org.opensearch.sql.expression.operator.convert; import static org.opensearch.sql.data.type.ExprCoreType.BOOLEAN; @@ -46,9 +45,7 @@ @UtilityClass public class TypeCastOperator { - /** - * Register Type Cast Operator. - */ + /** Register Type Cast Operator. */ public static void register(BuiltinFunctionRepository repository) { repository.register(castToString()); repository.register(castToByte()); @@ -64,148 +61,175 @@ public static void register(BuiltinFunctionRepository repository) { repository.register(castToDatetime()); } - private static DefaultFunctionResolver castToString() { - return FunctionDSL.define(BuiltinFunctionName.CAST_TO_STRING.getName(), + return FunctionDSL.define( + BuiltinFunctionName.CAST_TO_STRING.getName(), Stream.concat( - Arrays.asList(BYTE, SHORT, INTEGER, LONG, FLOAT, DOUBLE, BOOLEAN, TIME, DATE, - TIMESTAMP, DATETIME).stream() - .map(type -> impl( - nullMissingHandling((v) -> new ExprStringValue(v.value().toString())), - STRING, type)), - Stream.of(impl(nullMissingHandling((v) -> v), STRING, STRING))) - .collect(Collectors.toList()) - ); + Arrays.asList( + BYTE, SHORT, INTEGER, LONG, FLOAT, DOUBLE, BOOLEAN, TIME, DATE, TIMESTAMP, + DATETIME) + .stream() + .map( + type -> + impl( + nullMissingHandling( + (v) -> new ExprStringValue(v.value().toString())), + STRING, + type)), + Stream.of(impl(nullMissingHandling((v) -> v), STRING, STRING))) + .collect(Collectors.toList())); } private static DefaultFunctionResolver castToByte() { - return FunctionDSL.define(BuiltinFunctionName.CAST_TO_BYTE.getName(), - impl(nullMissingHandling( - (v) -> new ExprByteValue(Byte.valueOf(v.stringValue()))), BYTE, STRING), - impl(nullMissingHandling( - (v) -> new ExprByteValue(v.byteValue())), BYTE, DOUBLE), - impl(nullMissingHandling( - (v) -> new ExprByteValue(v.booleanValue() ? 1 : 0)), BYTE, BOOLEAN) - ); + return FunctionDSL.define( + BuiltinFunctionName.CAST_TO_BYTE.getName(), + impl( + nullMissingHandling((v) -> new ExprByteValue(Byte.valueOf(v.stringValue()))), + BYTE, + STRING), + impl(nullMissingHandling((v) -> new ExprByteValue(v.byteValue())), BYTE, DOUBLE), + impl( + nullMissingHandling((v) -> new ExprByteValue(v.booleanValue() ? 1 : 0)), + BYTE, + BOOLEAN)); } private static DefaultFunctionResolver castToShort() { - return FunctionDSL.define(BuiltinFunctionName.CAST_TO_SHORT.getName(), - impl(nullMissingHandling( - (v) -> new ExprShortValue(Short.valueOf(v.stringValue()))), SHORT, STRING), - impl(nullMissingHandling( - (v) -> new ExprShortValue(v.shortValue())), SHORT, DOUBLE), - impl(nullMissingHandling( - (v) -> new ExprShortValue(v.booleanValue() ? 1 : 0)), SHORT, BOOLEAN) - ); + return FunctionDSL.define( + BuiltinFunctionName.CAST_TO_SHORT.getName(), + impl( + nullMissingHandling((v) -> new ExprShortValue(Short.valueOf(v.stringValue()))), + SHORT, + STRING), + impl(nullMissingHandling((v) -> new ExprShortValue(v.shortValue())), SHORT, DOUBLE), + impl( + nullMissingHandling((v) -> new ExprShortValue(v.booleanValue() ? 1 : 0)), + SHORT, + BOOLEAN)); } private static DefaultFunctionResolver castToInt() { - return FunctionDSL.define(BuiltinFunctionName.CAST_TO_INT.getName(), - impl(nullMissingHandling( - (v) -> new ExprIntegerValue(Integer.valueOf(v.stringValue()))), INTEGER, STRING), - impl(nullMissingHandling( - (v) -> new ExprIntegerValue(v.integerValue())), INTEGER, DOUBLE), - impl(nullMissingHandling( - (v) -> new ExprIntegerValue(v.booleanValue() ? 1 : 0)), INTEGER, BOOLEAN) - ); + return FunctionDSL.define( + BuiltinFunctionName.CAST_TO_INT.getName(), + impl( + nullMissingHandling((v) -> new ExprIntegerValue(Integer.valueOf(v.stringValue()))), + INTEGER, + STRING), + impl(nullMissingHandling((v) -> new ExprIntegerValue(v.integerValue())), INTEGER, DOUBLE), + impl( + nullMissingHandling((v) -> new ExprIntegerValue(v.booleanValue() ? 1 : 0)), + INTEGER, + BOOLEAN)); } private static DefaultFunctionResolver castToLong() { - return FunctionDSL.define(BuiltinFunctionName.CAST_TO_LONG.getName(), - impl(nullMissingHandling( - (v) -> new ExprLongValue(Long.valueOf(v.stringValue()))), LONG, STRING), - impl(nullMissingHandling( - (v) -> new ExprLongValue(v.longValue())), LONG, DOUBLE), - impl(nullMissingHandling( - (v) -> new ExprLongValue(v.booleanValue() ? 1L : 0L)), LONG, BOOLEAN) - ); + return FunctionDSL.define( + BuiltinFunctionName.CAST_TO_LONG.getName(), + impl( + nullMissingHandling((v) -> new ExprLongValue(Long.valueOf(v.stringValue()))), + LONG, + STRING), + impl(nullMissingHandling((v) -> new ExprLongValue(v.longValue())), LONG, DOUBLE), + impl( + nullMissingHandling((v) -> new ExprLongValue(v.booleanValue() ? 1L : 0L)), + LONG, + BOOLEAN)); } private static DefaultFunctionResolver castToFloat() { - return FunctionDSL.define(BuiltinFunctionName.CAST_TO_FLOAT.getName(), - impl(nullMissingHandling( - (v) -> new ExprFloatValue(Float.valueOf(v.stringValue()))), FLOAT, STRING), - impl(nullMissingHandling( - (v) -> new ExprFloatValue(v.floatValue())), FLOAT, DOUBLE), - impl(nullMissingHandling( - (v) -> new ExprFloatValue(v.booleanValue() ? 1f : 0f)), FLOAT, BOOLEAN) - ); + return FunctionDSL.define( + BuiltinFunctionName.CAST_TO_FLOAT.getName(), + impl( + nullMissingHandling((v) -> new ExprFloatValue(Float.valueOf(v.stringValue()))), + FLOAT, + STRING), + impl(nullMissingHandling((v) -> new ExprFloatValue(v.floatValue())), FLOAT, DOUBLE), + impl( + nullMissingHandling((v) -> new ExprFloatValue(v.booleanValue() ? 1f : 0f)), + FLOAT, + BOOLEAN)); } private static DefaultFunctionResolver castToDouble() { - return FunctionDSL.define(BuiltinFunctionName.CAST_TO_DOUBLE.getName(), - impl(nullMissingHandling( - (v) -> new ExprDoubleValue(Double.valueOf(v.stringValue()))), DOUBLE, STRING), - impl(nullMissingHandling( - (v) -> new ExprDoubleValue(v.doubleValue())), DOUBLE, DOUBLE), - impl(nullMissingHandling( - (v) -> new ExprDoubleValue(v.booleanValue() ? 1D : 0D)), DOUBLE, BOOLEAN) - ); + return FunctionDSL.define( + BuiltinFunctionName.CAST_TO_DOUBLE.getName(), + impl( + nullMissingHandling((v) -> new ExprDoubleValue(Double.valueOf(v.stringValue()))), + DOUBLE, + STRING), + impl(nullMissingHandling((v) -> new ExprDoubleValue(v.doubleValue())), DOUBLE, DOUBLE), + impl( + nullMissingHandling((v) -> new ExprDoubleValue(v.booleanValue() ? 1D : 0D)), + DOUBLE, + BOOLEAN)); } private static DefaultFunctionResolver castToBoolean() { - return FunctionDSL.define(BuiltinFunctionName.CAST_TO_BOOLEAN.getName(), - impl(nullMissingHandling( - (v) -> ExprBooleanValue.of(Boolean.valueOf(v.stringValue()))), BOOLEAN, STRING), - impl(nullMissingHandling( - (v) -> ExprBooleanValue.of(v.doubleValue() != 0)), BOOLEAN, DOUBLE), - impl(nullMissingHandling((v) -> v), BOOLEAN, BOOLEAN) - ); + return FunctionDSL.define( + BuiltinFunctionName.CAST_TO_BOOLEAN.getName(), + impl( + nullMissingHandling((v) -> ExprBooleanValue.of(Boolean.valueOf(v.stringValue()))), + BOOLEAN, + STRING), + impl( + nullMissingHandling((v) -> ExprBooleanValue.of(v.doubleValue() != 0)), BOOLEAN, DOUBLE), + impl(nullMissingHandling((v) -> v), BOOLEAN, BOOLEAN)); } private static DefaultFunctionResolver castToDate() { - return FunctionDSL.define(BuiltinFunctionName.CAST_TO_DATE.getName(), - impl(nullMissingHandling( - (v) -> new ExprDateValue(v.stringValue())), DATE, STRING), - impl(nullMissingHandling( - (v) -> new ExprDateValue(v.dateValue())), DATE, DATETIME), - impl(nullMissingHandling( - (v) -> new ExprDateValue(v.dateValue())), DATE, TIMESTAMP), - impl(nullMissingHandling((v) -> v), DATE, DATE) - ); + return FunctionDSL.define( + BuiltinFunctionName.CAST_TO_DATE.getName(), + impl(nullMissingHandling((v) -> new ExprDateValue(v.stringValue())), DATE, STRING), + impl(nullMissingHandling((v) -> new ExprDateValue(v.dateValue())), DATE, DATETIME), + impl(nullMissingHandling((v) -> new ExprDateValue(v.dateValue())), DATE, TIMESTAMP), + impl(nullMissingHandling((v) -> v), DATE, DATE)); } private static DefaultFunctionResolver castToTime() { - return FunctionDSL.define(BuiltinFunctionName.CAST_TO_TIME.getName(), - impl(nullMissingHandling( - (v) -> new ExprTimeValue(v.stringValue())), TIME, STRING), - impl(nullMissingHandling( - (v) -> new ExprTimeValue(v.timeValue())), TIME, DATETIME), - impl(nullMissingHandling( - (v) -> new ExprTimeValue(v.timeValue())), TIME, TIMESTAMP), - impl(nullMissingHandling((v) -> v), TIME, TIME) - ); + return FunctionDSL.define( + BuiltinFunctionName.CAST_TO_TIME.getName(), + impl(nullMissingHandling((v) -> new ExprTimeValue(v.stringValue())), TIME, STRING), + impl(nullMissingHandling((v) -> new ExprTimeValue(v.timeValue())), TIME, DATETIME), + impl(nullMissingHandling((v) -> new ExprTimeValue(v.timeValue())), TIME, TIMESTAMP), + impl(nullMissingHandling((v) -> v), TIME, TIME)); } // `DATE`/`TIME`/`DATETIME` -> `DATETIME`/TIMESTAMP` cast tested in BinaryPredicateOperatorTest private static DefaultFunctionResolver castToTimestamp() { - return FunctionDSL.define(BuiltinFunctionName.CAST_TO_TIMESTAMP.getName(), - impl(nullMissingHandling( - (v) -> new ExprTimestampValue(v.stringValue())), TIMESTAMP, STRING), - impl(nullMissingHandling( - (v) -> new ExprTimestampValue(v.timestampValue())), TIMESTAMP, DATETIME), - impl(nullMissingHandling( - (v) -> new ExprTimestampValue(v.timestampValue())), TIMESTAMP, DATE), - implWithProperties(nullMissingHandlingWithProperties( - (fp, v) -> new ExprTimestampValue(((ExprTimeValue)v).timestampValue(fp))), - TIMESTAMP, TIME), - impl(nullMissingHandling((v) -> v), TIMESTAMP, TIMESTAMP) - ); + return FunctionDSL.define( + BuiltinFunctionName.CAST_TO_TIMESTAMP.getName(), + impl( + nullMissingHandling((v) -> new ExprTimestampValue(v.stringValue())), TIMESTAMP, STRING), + impl( + nullMissingHandling((v) -> new ExprTimestampValue(v.timestampValue())), + TIMESTAMP, + DATETIME), + impl( + nullMissingHandling((v) -> new ExprTimestampValue(v.timestampValue())), + TIMESTAMP, + DATE), + implWithProperties( + nullMissingHandlingWithProperties( + (fp, v) -> new ExprTimestampValue(((ExprTimeValue) v).timestampValue(fp))), + TIMESTAMP, + TIME), + impl(nullMissingHandling((v) -> v), TIMESTAMP, TIMESTAMP)); } private static DefaultFunctionResolver castToDatetime() { - return FunctionDSL.define(BuiltinFunctionName.CAST_TO_DATETIME.getName(), - impl(nullMissingHandling( - (v) -> new ExprDatetimeValue(v.stringValue())), DATETIME, STRING), - impl(nullMissingHandling( - (v) -> new ExprDatetimeValue(v.datetimeValue())), DATETIME, TIMESTAMP), - impl(nullMissingHandling( - (v) -> new ExprDatetimeValue(v.datetimeValue())), DATETIME, DATE), - implWithProperties(nullMissingHandlingWithProperties( - (fp, v) -> new ExprDatetimeValue(((ExprTimeValue)v).datetimeValue(fp))), - DATETIME, TIME), - impl(nullMissingHandling((v) -> v), DATETIME, DATETIME) - ); + return FunctionDSL.define( + BuiltinFunctionName.CAST_TO_DATETIME.getName(), + impl(nullMissingHandling((v) -> new ExprDatetimeValue(v.stringValue())), DATETIME, STRING), + impl( + nullMissingHandling((v) -> new ExprDatetimeValue(v.datetimeValue())), + DATETIME, + TIMESTAMP), + impl(nullMissingHandling((v) -> new ExprDatetimeValue(v.datetimeValue())), DATETIME, DATE), + implWithProperties( + nullMissingHandlingWithProperties( + (fp, v) -> new ExprDatetimeValue(((ExprTimeValue) v).datetimeValue(fp))), + DATETIME, + TIME), + impl(nullMissingHandling((v) -> v), DATETIME, DATETIME)); } } diff --git a/core/src/main/java/org/opensearch/sql/expression/operator/predicate/BinaryPredicateOperator.java b/core/src/main/java/org/opensearch/sql/expression/operator/predicate/BinaryPredicateOperator.java index cc5b47bde1..042a4f3ad4 100644 --- a/core/src/main/java/org/opensearch/sql/expression/operator/predicate/BinaryPredicateOperator.java +++ b/core/src/main/java/org/opensearch/sql/expression/operator/predicate/BinaryPredicateOperator.java @@ -3,7 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ - package org.opensearch.sql.expression.operator.predicate; import static org.opensearch.sql.data.model.ExprValueUtils.LITERAL_FALSE; @@ -30,11 +29,10 @@ import org.opensearch.sql.utils.OperatorUtils; /** - * The definition of binary predicate function - * and, Accepts two Boolean values and produces a Boolean. - * or, Accepts two Boolean values and produces a Boolean. - * xor, Accepts two Boolean values and produces a Boolean. - * equalTo, Compare the left expression and right expression and produces a Boolean. + * The definition of binary predicate function and, Accepts two Boolean values and produces a + * Boolean. or, Accepts two Boolean values and produces a Boolean. xor, Accepts two Boolean values + * and produces a Boolean. equalTo, Compare the left expression and right expression and produces a + * Boolean. */ @UtilityClass public class BinaryPredicateOperator { @@ -59,17 +57,8 @@ public static void register(BuiltinFunctionRepository repository) { } /** - * The and logic. - * A B A AND B - * TRUE TRUE TRUE - * TRUE FALSE FALSE - * TRUE NULL NULL - * TRUE MISSING MISSING - * FALSE FALSE FALSE - * FALSE NULL FALSE - * FALSE MISSING FALSE - * NULL NULL NULL - * NULL MISSING MISSING + * The and logic. A B A AND B TRUE TRUE TRUE TRUE FALSE FALSE TRUE NULL NULL TRUE MISSING MISSING + * FALSE FALSE FALSE FALSE NULL FALSE FALSE MISSING FALSE NULL NULL NULL NULL MISSING MISSING * MISSING MISSING MISSING */ private static Table andTable = @@ -87,18 +76,9 @@ public static void register(BuiltinFunctionRepository repository) { .build(); /** - * The or logic. - * A B A AND B - * TRUE TRUE TRUE - * TRUE FALSE TRUE - * TRUE NULL TRUE - * TRUE MISSING TRUE - * FALSE FALSE FALSE - * FALSE NULL NULL - * FALSE MISSING MISSING - * NULL NULL NULL - * NULL MISSING NULL - * MISSING MISSING MISSING + * The or logic. A B A AND B TRUE TRUE TRUE TRUE FALSE TRUE TRUE NULL TRUE TRUE MISSING TRUE FALSE + * FALSE FALSE FALSE NULL NULL FALSE MISSING MISSING NULL NULL NULL NULL MISSING NULL MISSING + * MISSING MISSING */ private static Table orTable = new ImmutableTable.Builder() @@ -115,17 +95,8 @@ public static void register(BuiltinFunctionRepository repository) { .build(); /** - * The xor logic. - * A B A AND B - * TRUE TRUE FALSE - * TRUE FALSE TRUE - * TRUE NULL TRUE - * TRUE MISSING TRUE - * FALSE FALSE FALSE - * FALSE NULL NULL - * FALSE MISSING MISSING - * NULL NULL NULL - * NULL MISSING NULL + * The xor logic. A B A AND B TRUE TRUE FALSE TRUE FALSE TRUE TRUE NULL TRUE TRUE MISSING TRUE + * FALSE FALSE FALSE FALSE NULL NULL FALSE MISSING MISSING NULL NULL NULL NULL MISSING NULL * MISSING MISSING MISSING */ private static Table xorTable = @@ -143,87 +114,132 @@ public static void register(BuiltinFunctionRepository repository) { .build(); private static DefaultFunctionResolver and() { - return define(BuiltinFunctionName.AND.getName(), + return define( + BuiltinFunctionName.AND.getName(), impl((v1, v2) -> lookupTableFunction(v1, v2, andTable), BOOLEAN, BOOLEAN, BOOLEAN)); } private static DefaultFunctionResolver or() { - return define(BuiltinFunctionName.OR.getName(), + return define( + BuiltinFunctionName.OR.getName(), impl((v1, v2) -> lookupTableFunction(v1, v2, orTable), BOOLEAN, BOOLEAN, BOOLEAN)); } private static DefaultFunctionResolver xor() { - return define(BuiltinFunctionName.XOR.getName(), + return define( + BuiltinFunctionName.XOR.getName(), impl((v1, v2) -> lookupTableFunction(v1, v2, xorTable), BOOLEAN, BOOLEAN, BOOLEAN)); } private static DefaultFunctionResolver equal() { - return define(BuiltinFunctionName.EQUAL.getName(), ExprCoreType.coreTypes().stream() - .map(type -> impl(nullMissingHandling( - (v1, v2) -> ExprBooleanValue.of(v1.equals(v2))), - BOOLEAN, type, type)) - .collect(Collectors.toList())); + return define( + BuiltinFunctionName.EQUAL.getName(), + ExprCoreType.coreTypes().stream() + .map( + type -> + impl( + nullMissingHandling((v1, v2) -> ExprBooleanValue.of(v1.equals(v2))), + BOOLEAN, + type, + type)) + .collect(Collectors.toList())); } private static DefaultFunctionResolver notEqual() { - return define(BuiltinFunctionName.NOTEQUAL.getName(), ExprCoreType.coreTypes().stream() - .map(type -> impl(nullMissingHandling( - (v1, v2) -> ExprBooleanValue.of(!v1.equals(v2))), - BOOLEAN, type, type)) - .collect(Collectors.toList())); + return define( + BuiltinFunctionName.NOTEQUAL.getName(), + ExprCoreType.coreTypes().stream() + .map( + type -> + impl( + nullMissingHandling((v1, v2) -> ExprBooleanValue.of(!v1.equals(v2))), + BOOLEAN, + type, + type)) + .collect(Collectors.toList())); } private static DefaultFunctionResolver less() { - return define(BuiltinFunctionName.LESS.getName(), ExprCoreType.coreTypes().stream() - .map(type -> impl(nullMissingHandling( - (v1, v2) -> ExprBooleanValue.of(v1.compareTo(v2) < 0)), - BOOLEAN,type, type)) - .collect(Collectors.toList())); + return define( + BuiltinFunctionName.LESS.getName(), + ExprCoreType.coreTypes().stream() + .map( + type -> + impl( + nullMissingHandling((v1, v2) -> ExprBooleanValue.of(v1.compareTo(v2) < 0)), + BOOLEAN, + type, + type)) + .collect(Collectors.toList())); } private static DefaultFunctionResolver lte() { - return define(BuiltinFunctionName.LTE.getName(), ExprCoreType.coreTypes().stream() - .map(type -> impl(nullMissingHandling( - (v1, v2) -> ExprBooleanValue.of(v1.compareTo(v2) <= 0)), - BOOLEAN, type, type)) - .collect(Collectors.toList())); + return define( + BuiltinFunctionName.LTE.getName(), + ExprCoreType.coreTypes().stream() + .map( + type -> + impl( + nullMissingHandling((v1, v2) -> ExprBooleanValue.of(v1.compareTo(v2) <= 0)), + BOOLEAN, + type, + type)) + .collect(Collectors.toList())); } private static DefaultFunctionResolver greater() { - return define(BuiltinFunctionName.GREATER.getName(), ExprCoreType.coreTypes().stream() - .map(type -> impl(nullMissingHandling( - (v1, v2) -> ExprBooleanValue.of(v1.compareTo(v2) > 0)), - BOOLEAN, type, type)) - .collect(Collectors.toList())); + return define( + BuiltinFunctionName.GREATER.getName(), + ExprCoreType.coreTypes().stream() + .map( + type -> + impl( + nullMissingHandling((v1, v2) -> ExprBooleanValue.of(v1.compareTo(v2) > 0)), + BOOLEAN, + type, + type)) + .collect(Collectors.toList())); } private static DefaultFunctionResolver gte() { - return define(BuiltinFunctionName.GTE.getName(), ExprCoreType.coreTypes().stream() - .map(type -> impl(nullMissingHandling( - (v1, v2) -> ExprBooleanValue.of(v1.compareTo(v2) >= 0)), - BOOLEAN, type, type)) - .collect(Collectors.toList())); + return define( + BuiltinFunctionName.GTE.getName(), + ExprCoreType.coreTypes().stream() + .map( + type -> + impl( + nullMissingHandling((v1, v2) -> ExprBooleanValue.of(v1.compareTo(v2) >= 0)), + BOOLEAN, + type, + type)) + .collect(Collectors.toList())); } private static DefaultFunctionResolver like() { - return define(BuiltinFunctionName.LIKE.getName(), + return define( + BuiltinFunctionName.LIKE.getName(), impl(nullMissingHandling(OperatorUtils::matches), BOOLEAN, STRING, STRING)); } private static DefaultFunctionResolver regexp() { - return define(BuiltinFunctionName.REGEXP.getName(), + return define( + BuiltinFunctionName.REGEXP.getName(), impl(nullMissingHandling(OperatorUtils::matchesRegexp), INTEGER, STRING, STRING)); } private static DefaultFunctionResolver notLike() { - return define(BuiltinFunctionName.NOT_LIKE.getName(), - impl(nullMissingHandling( - (v1, v2) -> UnaryPredicateOperator.not(OperatorUtils.matches(v1, v2))), - BOOLEAN, STRING, STRING)); + return define( + BuiltinFunctionName.NOT_LIKE.getName(), + impl( + nullMissingHandling( + (v1, v2) -> UnaryPredicateOperator.not(OperatorUtils.matches(v1, v2))), + BOOLEAN, + STRING, + STRING)); } - private static ExprValue lookupTableFunction(ExprValue arg1, ExprValue arg2, - Table table) { + private static ExprValue lookupTableFunction( + ExprValue arg1, ExprValue arg2, Table table) { if (table.contains(arg1, arg2)) { return table.get(arg1, arg2); } else { diff --git a/core/src/main/java/org/opensearch/sql/expression/operator/predicate/UnaryPredicateOperator.java b/core/src/main/java/org/opensearch/sql/expression/operator/predicate/UnaryPredicateOperator.java index 7d79d9d923..dbea762ae1 100644 --- a/core/src/main/java/org/opensearch/sql/expression/operator/predicate/UnaryPredicateOperator.java +++ b/core/src/main/java/org/opensearch/sql/expression/operator/predicate/UnaryPredicateOperator.java @@ -3,7 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ - package org.opensearch.sql.expression.operator.predicate; import static org.opensearch.sql.data.model.ExprValueUtils.LITERAL_NULL; @@ -28,14 +27,11 @@ import org.opensearch.sql.expression.function.SerializableFunction; /** - * The definition of unary predicate function - * not, Accepts one Boolean value and produces a Boolean. + * The definition of unary predicate function not, Accepts one Boolean value and produces a Boolean. */ @UtilityClass public class UnaryPredicateOperator { - /** - * Register Unary Predicate Function. - */ + /** Register Unary Predicate Function. */ public static void register(BuiltinFunctionRepository repository) { repository.register(not()); repository.register(isNotNull()); @@ -47,18 +43,12 @@ public static void register(BuiltinFunctionRepository repository) { } private static DefaultFunctionResolver not() { - return FunctionDSL.define(BuiltinFunctionName.NOT.getName(), FunctionDSL - .impl(UnaryPredicateOperator::not, BOOLEAN, BOOLEAN)); + return FunctionDSL.define( + BuiltinFunctionName.NOT.getName(), + FunctionDSL.impl(UnaryPredicateOperator::not, BOOLEAN, BOOLEAN)); } - /** - * The not logic. - * A NOT A - * TRUE FALSE - * FALSE TRUE - * NULL NULL - * MISSING MISSING - */ + /** The not logic. A NOT A TRUE FALSE FALSE TRUE NULL NULL MISSING MISSING */ public ExprValue not(ExprValue v) { if (v.isMissing() || v.isNull()) { return v; @@ -68,31 +58,33 @@ public ExprValue not(ExprValue v) { } private static DefaultFunctionResolver isNull(BuiltinFunctionName funcName) { - return FunctionDSL - .define(funcName.getName(), Arrays.stream(ExprCoreType.values()) - .map(type -> FunctionDSL - .impl((v) -> ExprBooleanValue.of(v.isNull()), BOOLEAN, type)) - .collect( - Collectors.toList())); + return FunctionDSL.define( + funcName.getName(), + Arrays.stream(ExprCoreType.values()) + .map(type -> FunctionDSL.impl((v) -> ExprBooleanValue.of(v.isNull()), BOOLEAN, type)) + .collect(Collectors.toList())); } private static DefaultFunctionResolver isNotNull() { - return FunctionDSL - .define(BuiltinFunctionName.IS_NOT_NULL.getName(), Arrays.stream(ExprCoreType.values()) - .map(type -> FunctionDSL - .impl((v) -> ExprBooleanValue.of(!v.isNull()), BOOLEAN, type)) - .collect( - Collectors.toList())); + return FunctionDSL.define( + BuiltinFunctionName.IS_NOT_NULL.getName(), + Arrays.stream(ExprCoreType.values()) + .map(type -> FunctionDSL.impl((v) -> ExprBooleanValue.of(!v.isNull()), BOOLEAN, type)) + .collect(Collectors.toList())); } private static DefaultFunctionResolver ifFunction() { FunctionName functionName = BuiltinFunctionName.IF.getName(); List typeList = ExprCoreType.coreTypes(); - List>> functionsOne = typeList.stream().map(v -> - impl((UnaryPredicateOperator::exprIf), v, BOOLEAN, v, v)) - .collect(Collectors.toList()); + List< + SerializableFunction< + FunctionName, + org.apache.commons.lang3.tuple.Pair>> + functionsOne = + typeList.stream() + .map(v -> impl((UnaryPredicateOperator::exprIf), v, BOOLEAN, v, v)) + .collect(Collectors.toList()); DefaultFunctionResolver functionResolver = FunctionDSL.define(functionName, functionsOne); return functionResolver; @@ -102,10 +94,14 @@ private static DefaultFunctionResolver ifNull() { FunctionName functionName = BuiltinFunctionName.IFNULL.getName(); List typeList = ExprCoreType.coreTypes(); - List>> functionsOne = typeList.stream().map(v -> - impl((UnaryPredicateOperator::exprIfNull), v, v, v)) - .collect(Collectors.toList()); + List< + SerializableFunction< + FunctionName, + org.apache.commons.lang3.tuple.Pair>> + functionsOne = + typeList.stream() + .map(v -> impl((UnaryPredicateOperator::exprIfNull), v, v, v)) + .collect(Collectors.toList()); DefaultFunctionResolver functionResolver = FunctionDSL.define(functionName, functionsOne); return functionResolver; @@ -116,14 +112,16 @@ private static DefaultFunctionResolver nullIf() { List typeList = ExprCoreType.coreTypes(); DefaultFunctionResolver functionResolver = - FunctionDSL.define(functionName, - typeList.stream().map(v -> - impl((UnaryPredicateOperator::exprNullIf), v, v, v)) - .collect(Collectors.toList())); + FunctionDSL.define( + functionName, + typeList.stream() + .map(v -> impl((UnaryPredicateOperator::exprNullIf), v, v, v)) + .collect(Collectors.toList())); return functionResolver; } - /** v2 if v1 is null. + /** + * v2 if v1 is null. * * @param v1 varable 1 * @param v2 varable 2 @@ -133,7 +131,8 @@ public static ExprValue exprIfNull(ExprValue v1, ExprValue v2) { return (v1.isNull() || v1.isMissing()) ? v2 : v1; } - /** return null if v1 equls to v2. + /** + * return null if v1 equls to v2. * * @param v1 varable 1 * @param v2 varable 2 @@ -146,5 +145,4 @@ public static ExprValue exprNullIf(ExprValue v1, ExprValue v2) { public static ExprValue exprIf(ExprValue v1, ExprValue v2, ExprValue v3) { return !v1.isNull() && !v1.isMissing() && LITERAL_TRUE.equals(v1) ? v2 : v3; } - } diff --git a/core/src/main/java/org/opensearch/sql/expression/parse/GrokExpression.java b/core/src/main/java/org/opensearch/sql/expression/parse/GrokExpression.java index 9797832f07..748ce5f559 100644 --- a/core/src/main/java/org/opensearch/sql/expression/parse/GrokExpression.java +++ b/core/src/main/java/org/opensearch/sql/expression/parse/GrokExpression.java @@ -20,9 +20,7 @@ import org.opensearch.sql.exception.ExpressionEvaluationException; import org.opensearch.sql.expression.Expression; -/** - * GrokExpression with grok patterns. - */ +/** GrokExpression with grok patterns. */ @EqualsAndHashCode(callSuper = true) @ToString public class GrokExpression extends ParseExpression { @@ -33,15 +31,14 @@ public class GrokExpression extends ParseExpression { grokCompiler.registerDefaultPatterns(); } - @EqualsAndHashCode.Exclude - private final Grok grok; + @EqualsAndHashCode.Exclude private final Grok grok; /** * GrokExpression. * * @param sourceField source text field - * @param pattern pattern used for parsing - * @param identifier derived field + * @param pattern pattern used for parsing + * @param identifier derived field */ public GrokExpression(Expression sourceField, Expression pattern, Expression identifier) { super("grok", sourceField, pattern, identifier); @@ -69,7 +66,9 @@ ExprValue parseValue(ExprValue value) throws ExpressionEvaluationException { */ public static List getNamedGroupCandidates(String pattern) { Grok grok = grokCompiler.compile(pattern); - return grok.namedGroups.stream().map(grok::getNamedRegexCollectionById) - .filter(group -> !group.equals("UNWANTED")).collect(Collectors.toUnmodifiableList()); + return grok.namedGroups.stream() + .map(grok::getNamedRegexCollectionById) + .filter(group -> !group.equals("UNWANTED")) + .collect(Collectors.toUnmodifiableList()); } } diff --git a/core/src/main/java/org/opensearch/sql/expression/parse/ParseExpression.java b/core/src/main/java/org/opensearch/sql/expression/parse/ParseExpression.java index 8d1ebcce08..6e2456ecc2 100644 --- a/core/src/main/java/org/opensearch/sql/expression/parse/ParseExpression.java +++ b/core/src/main/java/org/opensearch/sql/expression/parse/ParseExpression.java @@ -21,29 +21,25 @@ import org.opensearch.sql.expression.env.Environment; import org.opensearch.sql.expression.function.FunctionName; -/** - * ParseExpression. - */ +/** ParseExpression. */ @EqualsAndHashCode(callSuper = false) @ToString public abstract class ParseExpression extends FunctionExpression { - @Getter - protected final Expression sourceField; + @Getter protected final Expression sourceField; protected final Expression pattern; - @Getter - protected final Expression identifier; + @Getter protected final Expression identifier; protected final String identifierStr; /** * ParseExpression. * * @param functionName name of function expression - * @param sourceField source text field - * @param pattern pattern used for parsing - * @param identifier derived field + * @param sourceField source text field + * @param pattern pattern used for parsing + * @param identifier derived field */ - public ParseExpression(String functionName, Expression sourceField, Expression pattern, - Expression identifier) { + public ParseExpression( + String functionName, Expression sourceField, Expression pattern, Expression identifier) { super(FunctionName.of(functionName), ImmutableList.of(sourceField, pattern, identifier)); this.sourceField = sourceField; this.pattern = pattern; diff --git a/core/src/main/java/org/opensearch/sql/expression/parse/PatternsExpression.java b/core/src/main/java/org/opensearch/sql/expression/parse/PatternsExpression.java index 67160dad58..5b92779c35 100644 --- a/core/src/main/java/org/opensearch/sql/expression/parse/PatternsExpression.java +++ b/core/src/main/java/org/opensearch/sql/expression/parse/PatternsExpression.java @@ -17,30 +17,28 @@ import org.opensearch.sql.exception.ExpressionEvaluationException; import org.opensearch.sql.expression.Expression; -/** - * PatternsExpression with regex filter. - */ +/** PatternsExpression with regex filter. */ @EqualsAndHashCode(callSuper = true) @ToString public class PatternsExpression extends ParseExpression { - /** - * Default name of the derived field. - */ + /** Default name of the derived field. */ public static final String DEFAULT_NEW_FIELD = "patterns_field"; - private static final ImmutableSet DEFAULT_IGNORED_CHARS = ImmutableSet.copyOf( - "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".chars() - .mapToObj(c -> (char) c).toArray(Character[]::new)); + private static final ImmutableSet DEFAULT_IGNORED_CHARS = + ImmutableSet.copyOf( + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" + .chars() + .mapToObj(c -> (char) c) + .toArray(Character[]::new)); private final boolean useCustomPattern; - @EqualsAndHashCode.Exclude - private Pattern pattern; + @EqualsAndHashCode.Exclude private Pattern pattern; /** * PatternsExpression. * * @param sourceField source text field - * @param pattern pattern used for parsing - * @param identifier derived field + * @param pattern pattern used for parsing + * @param identifier derived field */ public PatternsExpression(Expression sourceField, Expression pattern, Expression identifier) { super("patterns", sourceField, pattern, identifier); diff --git a/core/src/main/java/org/opensearch/sql/expression/parse/RegexExpression.java b/core/src/main/java/org/opensearch/sql/expression/parse/RegexExpression.java index f3a3ff0b66..7514c9df69 100644 --- a/core/src/main/java/org/opensearch/sql/expression/parse/RegexExpression.java +++ b/core/src/main/java/org/opensearch/sql/expression/parse/RegexExpression.java @@ -19,24 +19,20 @@ import org.opensearch.sql.exception.ExpressionEvaluationException; import org.opensearch.sql.expression.Expression; -/** - * RegexExpression with regex and named capture group. - */ +/** RegexExpression with regex and named capture group. */ @EqualsAndHashCode(callSuper = true) @ToString public class RegexExpression extends ParseExpression { private static final Logger log = LogManager.getLogger(RegexExpression.class); private static final Pattern GROUP_PATTERN = Pattern.compile("\\(\\?<([a-zA-Z][a-zA-Z0-9]*)>"); - @Getter - @EqualsAndHashCode.Exclude - private final Pattern regexPattern; + @Getter @EqualsAndHashCode.Exclude private final Pattern regexPattern; /** * RegexExpression. * * @param sourceField source text field - * @param pattern pattern used for parsing - * @param identifier derived field + * @param pattern pattern used for parsing + * @param identifier derived field */ public RegexExpression(Expression sourceField, Expression pattern, Expression identifier) { super("regex", sourceField, pattern, identifier); diff --git a/core/src/main/java/org/opensearch/sql/expression/span/SpanExpression.java b/core/src/main/java/org/opensearch/sql/expression/span/SpanExpression.java index aff114145e..a4db50944c 100644 --- a/core/src/main/java/org/opensearch/sql/expression/span/SpanExpression.java +++ b/core/src/main/java/org/opensearch/sql/expression/span/SpanExpression.java @@ -24,9 +24,7 @@ public class SpanExpression implements Expression { private final Expression value; private final SpanUnit unit; - /** - * Construct a span expression by field and span interval expression. - */ + /** Construct a span expression by field and span interval expression. */ public SpanExpression(Expression field, Expression value, SpanUnit unit) { this.field = field; this.value = value; @@ -35,18 +33,15 @@ public SpanExpression(Expression field, Expression value, SpanUnit unit) { @Override public ExprValue valueOf(Environment valueEnv) { - Rounding rounding = Rounding.createRounding(this); //TODO: will integrate with WindowAssigner + Rounding rounding = + Rounding.createRounding(this); // TODO: will integrate with WindowAssigner return rounding.round(field.valueOf(valueEnv)); } /** - * Return type follows the following table. - * FIELD VALUE RETURN_TYPE - * int/long integer int/long (field type) - * int/long double double - * float/double integer float/double (field type) - * float/double double float/double (field type) - * other any field type + * Return type follows the following table. FIELD VALUE RETURN_TYPE int/long integer int/long + * (field type) int/long double double float/double integer float/double (field type) float/double + * double float/double (field type) other any field type */ @Override public ExprType type() { diff --git a/core/src/main/java/org/opensearch/sql/expression/system/SystemFunctions.java b/core/src/main/java/org/opensearch/sql/expression/system/SystemFunctions.java index e12bcd0a58..cf071c4f31 100644 --- a/core/src/main/java/org/opensearch/sql/expression/system/SystemFunctions.java +++ b/core/src/main/java/org/opensearch/sql/expression/system/SystemFunctions.java @@ -24,9 +24,7 @@ @UtilityClass public class SystemFunctions { - /** - * Register TypeOf Operator. - */ + /** Register TypeOf Operator. */ public static void register(BuiltinFunctionRepository repository) { repository.register(typeof()); } @@ -37,19 +35,20 @@ private static FunctionResolver typeof() { @Override public Pair resolve( FunctionSignature unresolvedSignature) { - return Pair.of(unresolvedSignature, + return Pair.of( + unresolvedSignature, (functionProperties, arguments) -> new FunctionExpression(BuiltinFunctionName.TYPEOF.getName(), arguments) { - @Override - public ExprValue valueOf(Environment valueEnv) { - return new ExprStringValue(getArguments().get(0).type().legacyTypeName()); - } + @Override + public ExprValue valueOf(Environment valueEnv) { + return new ExprStringValue(getArguments().get(0).type().legacyTypeName()); + } - @Override - public ExprType type() { - return STRING; - } - }); + @Override + public ExprType type() { + return STRING; + } + }); } @Override diff --git a/core/src/main/java/org/opensearch/sql/expression/text/TextFunction.java b/core/src/main/java/org/opensearch/sql/expression/text/TextFunction.java index e56c85a0c8..1ba5854596 100644 --- a/core/src/main/java/org/opensearch/sql/expression/text/TextFunction.java +++ b/core/src/main/java/org/opensearch/sql/expression/text/TextFunction.java @@ -3,7 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ - package org.opensearch.sql.expression.text; import static org.opensearch.sql.data.type.ExprCoreType.ARRAY; @@ -35,9 +34,8 @@ import org.opensearch.sql.expression.function.SerializableTriFunction; /** - * The definition of text functions. - * 1) have the clear interface for function define. - * 2) the implementation should rely on ExprValue. + * The definition of text functions. 1) have the clear interface for function define. 2) the + * implementation should rely on ExprValue. */ @UtilityClass public class TextFunction { @@ -70,17 +68,20 @@ public void register(BuiltinFunctionRepository repository) { } /** - * Gets substring starting at given point, for optional given length. - * Form of this function using keywords instead of comma delimited variables is not supported. - * Supports following signatures: + * Gets substring starting at given point, for optional given length. Form of this function using + * keywords instead of comma delimited variables is not supported. Supports following signatures: * (STRING, INTEGER)/(STRING, INTEGER, INTEGER) -> STRING */ private DefaultFunctionResolver substringSubstr(FunctionName functionName) { - return define(functionName, - impl(nullMissingHandling(TextFunction::exprSubstrStart), - STRING, STRING, INTEGER), - impl(nullMissingHandling(TextFunction::exprSubstrStartLength), - STRING, STRING, INTEGER, INTEGER)); + return define( + functionName, + impl(nullMissingHandling(TextFunction::exprSubstrStart), STRING, STRING, INTEGER), + impl( + nullMissingHandling(TextFunction::exprSubstrStartLength), + STRING, + STRING, + INTEGER, + INTEGER)); } private DefaultFunctionResolver substring() { @@ -91,223 +92,235 @@ private DefaultFunctionResolver substr() { return substringSubstr(BuiltinFunctionName.SUBSTR.getName()); } - /** - * Removes leading whitespace from string. - * Supports following signatures: - * STRING -> STRING - */ + /** Removes leading whitespace from string. Supports following signatures: STRING -> STRING */ private DefaultFunctionResolver ltrim() { - return define(BuiltinFunctionName.LTRIM.getName(), - impl(nullMissingHandling((v) -> new ExprStringValue(v.stringValue().stripLeading())), - STRING, STRING)); + return define( + BuiltinFunctionName.LTRIM.getName(), + impl( + nullMissingHandling((v) -> new ExprStringValue(v.stringValue().stripLeading())), + STRING, + STRING)); } - /** - * Removes trailing whitespace from string. - * Supports following signatures: - * STRING -> STRING - */ + /** Removes trailing whitespace from string. Supports following signatures: STRING -> STRING */ private DefaultFunctionResolver rtrim() { - return define(BuiltinFunctionName.RTRIM.getName(), - impl(nullMissingHandling((v) -> new ExprStringValue(v.stringValue().stripTrailing())), - STRING, STRING)); + return define( + BuiltinFunctionName.RTRIM.getName(), + impl( + nullMissingHandling((v) -> new ExprStringValue(v.stringValue().stripTrailing())), + STRING, + STRING)); } /** - * Removes leading and trailing whitespace from string. - * Has option to specify a String to trim instead of whitespace but this is not yet supported. - * Supporting String specification requires finding keywords inside TRIM command. - * Supports following signatures: - * STRING -> STRING + * Removes leading and trailing whitespace from string. Has option to specify a String to trim + * instead of whitespace but this is not yet supported. Supporting String specification requires + * finding keywords inside TRIM command. Supports following signatures: STRING -> STRING */ private DefaultFunctionResolver trim() { - return define(BuiltinFunctionName.TRIM.getName(), - impl(nullMissingHandling((v) -> new ExprStringValue(v.stringValue().trim())), - STRING, STRING)); + return define( + BuiltinFunctionName.TRIM.getName(), + impl( + nullMissingHandling((v) -> new ExprStringValue(v.stringValue().trim())), + STRING, + STRING)); } - /** - * Converts String to lowercase. - * Supports following signatures: - * STRING -> STRING - */ + /** Converts String to lowercase. Supports following signatures: STRING -> STRING */ private DefaultFunctionResolver lower() { - return define(BuiltinFunctionName.LOWER.getName(), - impl(nullMissingHandling((v) -> new ExprStringValue((v.stringValue().toLowerCase()))), - STRING, STRING) - ); + return define( + BuiltinFunctionName.LOWER.getName(), + impl( + nullMissingHandling((v) -> new ExprStringValue((v.stringValue().toLowerCase()))), + STRING, + STRING)); } - /** - * Converts String to uppercase. - * Supports following signatures: - * STRING -> STRING - */ + /** Converts String to uppercase. Supports following signatures: STRING -> STRING */ private DefaultFunctionResolver upper() { - return define(BuiltinFunctionName.UPPER.getName(), - impl(nullMissingHandling((v) -> new ExprStringValue((v.stringValue().toUpperCase()))), - STRING, STRING) - ); + return define( + BuiltinFunctionName.UPPER.getName(), + impl( + nullMissingHandling((v) -> new ExprStringValue((v.stringValue().toUpperCase()))), + STRING, + STRING)); } /** - * Concatenates a list of Strings. - * Supports following signatures: - * (STRING, STRING, ...., STRING) -> STRING + * Concatenates a list of Strings. Supports following signatures: (STRING, STRING, ...., STRING) + * -> STRING */ private DefaultFunctionResolver concat() { FunctionName concatFuncName = BuiltinFunctionName.CONCAT.getName(); - return define(concatFuncName, funcName -> + return define( + concatFuncName, + funcName -> Pair.of( - new FunctionSignature(concatFuncName, Collections.singletonList(ARRAY)), - (funcProp, args) -> new FunctionExpression(funcName, args) { + new FunctionSignature(concatFuncName, Collections.singletonList(ARRAY)), + (funcProp, args) -> + new FunctionExpression(funcName, args) { @Override public ExprValue valueOf(Environment valueEnv) { - List exprValues = args.stream() - .map(arg -> arg.valueOf(valueEnv)).collect(Collectors.toList()); - if (exprValues.stream().anyMatch(ExprValue::isMissing)) { - return ExprValueUtils.missingValue(); - } - if (exprValues.stream().anyMatch(ExprValue::isNull)) { - return ExprValueUtils.nullValue(); - } - return new ExprStringValue(exprValues.stream() - .map(ExprValue::stringValue) - .collect(Collectors.joining())); + List exprValues = + args.stream() + .map(arg -> arg.valueOf(valueEnv)) + .collect(Collectors.toList()); + if (exprValues.stream().anyMatch(ExprValue::isMissing)) { + return ExprValueUtils.missingValue(); + } + if (exprValues.stream().anyMatch(ExprValue::isNull)) { + return ExprValueUtils.nullValue(); + } + return new ExprStringValue( + exprValues.stream() + .map(ExprValue::stringValue) + .collect(Collectors.joining())); } @Override public ExprType type() { return STRING; } - } - )); + })); } /** - * TODO: https://github.com/opendistro-for-elasticsearch/sql/issues/710 - * Extend to accept variable argument amounts. - * Concatenates a list of Strings with a separator string. - * Supports following signatures: - * (STRING, STRING, STRING) -> STRING + * TODO: https://github.com/opendistro-for-elasticsearch/sql/issues/710 Extend to accept variable + * argument amounts. Concatenates a list of Strings with a separator string. Supports following + * signatures: (STRING, STRING, STRING) -> STRING */ private DefaultFunctionResolver concat_ws() { - return define(BuiltinFunctionName.CONCAT_WS.getName(), - impl(nullMissingHandling((sep, str1, str2) -> - new ExprStringValue(str1.stringValue() + sep.stringValue() + str2.stringValue())), - STRING, STRING, STRING, STRING)); + return define( + BuiltinFunctionName.CONCAT_WS.getName(), + impl( + nullMissingHandling( + (sep, str1, str2) -> + new ExprStringValue( + str1.stringValue() + sep.stringValue() + str2.stringValue())), + STRING, + STRING, + STRING, + STRING)); } - /** - * Calculates length of String in bytes. - * Supports following signatures: - * STRING -> INTEGER - */ + /** Calculates length of String in bytes. Supports following signatures: STRING -> INTEGER */ private DefaultFunctionResolver length() { - return define(BuiltinFunctionName.LENGTH.getName(), - impl(nullMissingHandling((str) -> - new ExprIntegerValue(str.stringValue().getBytes().length)), INTEGER, STRING)); + return define( + BuiltinFunctionName.LENGTH.getName(), + impl( + nullMissingHandling((str) -> new ExprIntegerValue(str.stringValue().getBytes().length)), + INTEGER, + STRING)); } /** - * Does String comparison of two Strings and returns Integer value. - * Supports following signatures: + * Does String comparison of two Strings and returns Integer value. Supports following signatures: * (STRING, STRING) -> INTEGER */ private DefaultFunctionResolver strcmp() { - return define(BuiltinFunctionName.STRCMP.getName(), - impl(nullMissingHandling((str1, str2) -> - new ExprIntegerValue(Integer.compare( - str1.stringValue().compareTo(str2.stringValue()), 0))), - INTEGER, STRING, STRING)); + return define( + BuiltinFunctionName.STRCMP.getName(), + impl( + nullMissingHandling( + (str1, str2) -> + new ExprIntegerValue( + Integer.compare(str1.stringValue().compareTo(str2.stringValue()), 0))), + INTEGER, + STRING, + STRING)); } /** * Returns the rightmost len characters from the string str, or NULL if any argument is NULL. - * Supports following signatures: - * (STRING, INTEGER) -> STRING + * Supports following signatures: (STRING, INTEGER) -> STRING */ private DefaultFunctionResolver right() { - return define(BuiltinFunctionName.RIGHT.getName(), - impl(nullMissingHandling(TextFunction::exprRight), STRING, STRING, INTEGER)); + return define( + BuiltinFunctionName.RIGHT.getName(), + impl(nullMissingHandling(TextFunction::exprRight), STRING, STRING, INTEGER)); } /** * Returns the leftmost len characters from the string str, or NULL if any argument is NULL. - * Supports following signature: - * (STRING, INTEGER) -> STRING + * Supports following signature: (STRING, INTEGER) -> STRING */ private DefaultFunctionResolver left() { - return define(BuiltinFunctionName.LEFT.getName(), + return define( + BuiltinFunctionName.LEFT.getName(), impl(nullMissingHandling(TextFunction::exprLeft), STRING, STRING, INTEGER)); } /** - * Returns the numeric value of the leftmost character of the string str. - * Returns 0 if str is the empty string. Returns NULL if str is NULL. - * ASCII() works for 8-bit characters. - * Supports following signature: - * STRING -> INTEGER + * Returns the numeric value of the leftmost character of the string str. Returns 0 if str is the + * empty string. Returns NULL if str is NULL. ASCII() works for 8-bit characters. Supports + * following signature: STRING -> INTEGER */ private DefaultFunctionResolver ascii() { - return define(BuiltinFunctionName.ASCII.getName(), + return define( + BuiltinFunctionName.ASCII.getName(), impl(nullMissingHandling(TextFunction::exprAscii), INTEGER, STRING)); } /** - * LOCATE(substr, str) returns the position of the first occurrence of substring substr - * in string str. LOCATE(substr, str, pos) returns the position of the first occurrence - * of substring substr in string str, starting at position pos. - * Returns 0 if substr is not in str. - * Returns NULL if any argument is NULL. - * Supports following signature: - * (STRING, STRING) -> INTEGER - * (STRING, STRING, INTEGER) -> INTEGER + * LOCATE(substr, str) returns the position of the first occurrence of substring substr in string + * str. LOCATE(substr, str, pos) returns the position of the first occurrence of substring substr + * in string str, starting at position pos. Returns 0 if substr is not in str. Returns NULL if any + * argument is NULL. Supports following signature: (STRING, STRING) -> INTEGER (STRING, STRING, + * INTEGER) -> INTEGER */ private DefaultFunctionResolver locate() { - return define(BuiltinFunctionName.LOCATE.getName(), - impl(nullMissingHandling( - (SerializableBiFunction) - TextFunction::exprLocate), INTEGER, STRING, STRING), - impl(nullMissingHandling( - (SerializableTriFunction) - TextFunction::exprLocate), INTEGER, STRING, STRING, INTEGER)); + return define( + BuiltinFunctionName.LOCATE.getName(), + impl( + nullMissingHandling( + (SerializableBiFunction) TextFunction::exprLocate), + INTEGER, + STRING, + STRING), + impl( + nullMissingHandling( + (SerializableTriFunction) + TextFunction::exprLocate), + INTEGER, + STRING, + STRING, + INTEGER)); } /** * Returns the position of the first occurrence of a substring in a string starting from 1. - * Returns 0 if substring is not in string. - * Returns NULL if any argument is NULL. - * Supports following signature: - * (STRING IN STRING) -> INTEGER + * Returns 0 if substring is not in string. Returns NULL if any argument is NULL. Supports + * following signature: (STRING IN STRING) -> INTEGER */ private DefaultFunctionResolver position() { - return define(BuiltinFunctionName.POSITION.getName(), - impl(nullMissingHandling( - (SerializableBiFunction) - TextFunction::exprLocate), INTEGER, STRING, STRING)); + return define( + BuiltinFunctionName.POSITION.getName(), + impl( + nullMissingHandling( + (SerializableBiFunction) TextFunction::exprLocate), + INTEGER, + STRING, + STRING)); } /** - * REPLACE(str, from_str, to_str) returns the string str with all occurrences of - * the string from_str replaced by the string to_str. - * REPLACE() performs a case-sensitive match when searching for from_str. - * Supports following signature: - * (STRING, STRING, STRING) -> STRING + * REPLACE(str, from_str, to_str) returns the string str with all occurrences of the string + * from_str replaced by the string to_str. REPLACE() performs a case-sensitive match when + * searching for from_str. Supports following signature: (STRING, STRING, STRING) -> STRING */ private DefaultFunctionResolver replace() { - return define(BuiltinFunctionName.REPLACE.getName(), + return define( + BuiltinFunctionName.REPLACE.getName(), impl(nullMissingHandling(TextFunction::exprReplace), STRING, STRING, STRING, STRING)); } /** - * REVERSE(str) returns reversed string of the string supplied as an argument - * Returns NULL if the argument is NULL. - * Supports the following signature: - * (STRING) -> STRING + * REVERSE(str) returns reversed string of the string supplied as an argument Returns NULL if the + * argument is NULL. Supports the following signature: (STRING) -> STRING */ private DefaultFunctionResolver reverse() { - return define(BuiltinFunctionName.REVERSE.getName(), + return define( + BuiltinFunctionName.REVERSE.getName(), impl(nullMissingHandling(TextFunction::exprReverse), STRING, STRING)); } @@ -321,7 +334,7 @@ private static ExprValue exprSubstrStart(ExprValue exprValue, ExprValue start) { } private static ExprValue exprSubstrStartLength( - ExprValue exprValue, ExprValue start, ExprValue length) { + ExprValue exprValue, ExprValue start, ExprValue length) { int startIdx = start.integerValue(); int len = length.integerValue(); if ((startIdx == 0) || (len == 0)) { @@ -379,4 +392,3 @@ private static ExprValue exprReverse(ExprValue str) { return new ExprStringValue(new StringBuilder(str.stringValue()).reverse().toString()); } } - diff --git a/core/src/main/java/org/opensearch/sql/expression/window/WindowDefinition.java b/core/src/main/java/org/opensearch/sql/expression/window/WindowDefinition.java index 24751633de..2030ce8062 100644 --- a/core/src/main/java/org/opensearch/sql/expression/window/WindowDefinition.java +++ b/core/src/main/java/org/opensearch/sql/expression/window/WindowDefinition.java @@ -3,7 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ - package org.opensearch.sql.expression.window; import static org.opensearch.sql.ast.tree.Sort.SortOption; @@ -16,9 +15,7 @@ import org.apache.commons.lang3.tuple.Pair; import org.opensearch.sql.expression.Expression; -/** - * Window definition that consists of partition and sort by information for a window. - */ +/** Window definition that consists of partition and sort by information for a window. */ @Data public class WindowDefinition { @@ -27,7 +24,8 @@ public class WindowDefinition { /** * Return all items in partition by and sort list. - * @return all sort items + * + * @return all sort items */ public List> getAllSortItems() { List> allSorts = new ArrayList<>(); @@ -35,5 +33,4 @@ public List> getAllSortItems() { allSorts.addAll(sortList); return allSorts; } - } diff --git a/core/src/main/java/org/opensearch/sql/expression/window/WindowFunctionExpression.java b/core/src/main/java/org/opensearch/sql/expression/window/WindowFunctionExpression.java index a15919bf03..f323494307 100644 --- a/core/src/main/java/org/opensearch/sql/expression/window/WindowFunctionExpression.java +++ b/core/src/main/java/org/opensearch/sql/expression/window/WindowFunctionExpression.java @@ -3,27 +3,22 @@ * SPDX-License-Identifier: Apache-2.0 */ - package org.opensearch.sql.expression.window; import org.opensearch.sql.expression.Expression; import org.opensearch.sql.expression.window.frame.WindowFrame; -/** - * Window function abstraction. - */ +/** Window function abstraction. */ public interface WindowFunctionExpression extends Expression { /** - * Create specific window frame based on window definition and what's current window function. - * For now two types of cumulative window frame is returned: - * 1. Ranking window functions: ignore frame definition and always operates on - * previous and current row. - * 2. Aggregate window functions: frame partition into peers and sliding window is not supported. + * Create specific window frame based on window definition and what's current window function. For + * now two types of cumulative window frame is returned: 1. Ranking window functions: ignore frame + * definition and always operates on previous and current row. 2. Aggregate window functions: + * frame partition into peers and sliding window is not supported. * * @param definition window definition - * @return window frame + * @return window frame */ WindowFrame createWindowFrame(WindowDefinition definition); - } diff --git a/core/src/main/java/org/opensearch/sql/expression/window/WindowFunctions.java b/core/src/main/java/org/opensearch/sql/expression/window/WindowFunctions.java index 9a9e0c4c86..3df59c52c0 100644 --- a/core/src/main/java/org/opensearch/sql/expression/window/WindowFunctions.java +++ b/core/src/main/java/org/opensearch/sql/expression/window/WindowFunctions.java @@ -3,7 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ - package org.opensearch.sql.expression.window; import static java.util.Collections.emptyList; @@ -22,16 +21,14 @@ import org.opensearch.sql.expression.window.ranking.RankingWindowFunction; import org.opensearch.sql.expression.window.ranking.RowNumberFunction; -/** - * Window functions that register all window functions in function repository. - */ +/** Window functions that register all window functions in function repository. */ @UtilityClass public class WindowFunctions { /** * Register all window functions to function repository. * - * @param repository function repository + * @param repository function repository */ public void register(BuiltinFunctionRepository repository) { repository.register(rowNumber()); @@ -51,11 +48,11 @@ private DefaultFunctionResolver denseRank() { return rankingFunction(BuiltinFunctionName.DENSE_RANK.getName(), DenseRankFunction::new); } - private DefaultFunctionResolver rankingFunction(FunctionName functionName, - Supplier constructor) { + private DefaultFunctionResolver rankingFunction( + FunctionName functionName, Supplier constructor) { FunctionSignature functionSignature = new FunctionSignature(functionName, emptyList()); FunctionBuilder functionBuilder = (functionProperties, arguments) -> constructor.get(); - return new DefaultFunctionResolver(functionName, - ImmutableMap.of(functionSignature, functionBuilder)); + return new DefaultFunctionResolver( + functionName, ImmutableMap.of(functionSignature, functionBuilder)); } } diff --git a/core/src/main/java/org/opensearch/sql/expression/window/aggregation/AggregateWindowFunction.java b/core/src/main/java/org/opensearch/sql/expression/window/aggregation/AggregateWindowFunction.java index 604f65e6ff..63922ac3fd 100644 --- a/core/src/main/java/org/opensearch/sql/expression/window/aggregation/AggregateWindowFunction.java +++ b/core/src/main/java/org/opensearch/sql/expression/window/aggregation/AggregateWindowFunction.java @@ -3,7 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ - package org.opensearch.sql.expression.window.aggregation; import java.util.List; @@ -21,9 +20,7 @@ import org.opensearch.sql.expression.window.frame.PeerRowsWindowFrame; import org.opensearch.sql.expression.window.frame.WindowFrame; -/** - * Aggregate function adapter that adapts Aggregator for window operator use. - */ +/** Aggregate function adapter that adapts Aggregator for window operator use. */ @EqualsAndHashCode @RequiredArgsConstructor public class AggregateWindowFunction implements WindowFunctionExpression { @@ -64,5 +61,4 @@ public T accept(ExpressionNodeVisitor visitor, C context) { public String toString() { return aggregator.toString(); } - } diff --git a/core/src/main/java/org/opensearch/sql/expression/window/frame/CurrentRowWindowFrame.java b/core/src/main/java/org/opensearch/sql/expression/window/frame/CurrentRowWindowFrame.java index 06b19a1488..359486a4ef 100644 --- a/core/src/main/java/org/opensearch/sql/expression/window/frame/CurrentRowWindowFrame.java +++ b/core/src/main/java/org/opensearch/sql/expression/window/frame/CurrentRowWindowFrame.java @@ -3,7 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ - package org.opensearch.sql.expression.window.frame; import com.google.common.collect.PeekingIterator; @@ -21,18 +20,17 @@ import org.opensearch.sql.expression.window.WindowDefinition; /** - * Conceptually, cumulative window frame should hold all seen rows till next partition. - * This class is actually an optimized version that only hold previous and current row. This is - * efficient and sufficient for ranking and aggregate window function support for now, though need - * to add "real" cumulative frame implementation in future as needed. + * Conceptually, cumulative window frame should hold all seen rows till next partition. This class + * is actually an optimized version that only hold previous and current row. This is efficient and + * sufficient for ranking and aggregate window function support for now, though need to add "real" + * cumulative frame implementation in future as needed. */ @EqualsAndHashCode @RequiredArgsConstructor @ToString public class CurrentRowWindowFrame implements WindowFrame { - @Getter - private final WindowDefinition windowDefinition; + @Getter private final WindowDefinition windowDefinition; private ExprValue previous; private ExprValue current; @@ -67,14 +65,12 @@ public ExprValue previous() { private List resolve(List expressions, ExprValue row) { Environment valueEnv = row.bindingTuples(); - return expressions.stream() - .map(expr -> expr.valueOf(valueEnv)) - .collect(Collectors.toList()); + return expressions.stream().map(expr -> expr.valueOf(valueEnv)).collect(Collectors.toList()); } /** - * Current row window frame won't pre-fetch any row ahead. - * So always return false as nothing "cached" in frame. + * Current row window frame won't pre-fetch any row ahead. So always return false as nothing + * "cached" in frame. */ @Override public boolean hasNext() { @@ -85,5 +81,4 @@ public boolean hasNext() { public List next() { return Collections.emptyList(); } - } diff --git a/core/src/main/java/org/opensearch/sql/expression/window/frame/PeerRowsWindowFrame.java b/core/src/main/java/org/opensearch/sql/expression/window/frame/PeerRowsWindowFrame.java index a3e8de40c1..0ec2042b1e 100644 --- a/core/src/main/java/org/opensearch/sql/expression/window/frame/PeerRowsWindowFrame.java +++ b/core/src/main/java/org/opensearch/sql/expression/window/frame/PeerRowsWindowFrame.java @@ -3,7 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ - package org.opensearch.sql.expression.window.frame; import com.google.common.collect.PeekingIterator; @@ -19,9 +18,9 @@ import org.opensearch.sql.expression.window.WindowDefinition; /** - * Window frame that only keep peers (tuples with same value of fields specified in sort list - * in window definition). See PeerWindowFrameTest for details about how this window frame - * interacts with window operator and window function. + * Window frame that only keep peers (tuples with same value of fields specified in sort list in + * window definition). See PeerWindowFrameTest for details about how this window frame interacts + * with window operator and window function. */ @RequiredArgsConstructor public class PeerRowsWindowFrame implements WindowFrame { @@ -29,33 +28,26 @@ public class PeerRowsWindowFrame implements WindowFrame { private final WindowDefinition windowDefinition; /** - * All peer rows (peer means rows in a partition that share same sort key - * based on sort list in window definition. + * All peer rows (peer means rows in a partition that share same sort key based on sort list in + * window definition. */ private final List peers = new ArrayList<>(); - /** - * Which row in the peer is currently being enriched by window function. - */ + /** Which row in the peer is currently being enriched by window function. */ private int position; - /** - * Does row at current position represents a new partition. - */ + /** Does row at current position represents a new partition. */ private boolean isNewPartition = true; - /** - * If any more pre-fetched rows not returned to window operator yet. - */ + /** If any more pre-fetched rows not returned to window operator yet. */ @Override public boolean hasNext() { return position < peers.size(); } /** - * Move position and clear new partition flag. - * Note that because all peer rows have same result from window function, - * this is only returned at first time to change window function state. + * Move position and clear new partition flag. Note that because all peer rows have same result + * from window function, this is only returned at first time to change window function state. * Afterwards, empty list is returned to avoid changes until next peer loaded. * * @return all rows for the peer @@ -70,8 +62,9 @@ public List next() { } /** - * Current row at the position. Because rows are pre-fetched here, - * window operator needs to get them from here too. + * Current row at the position. Because rows are pre-fetched here, window operator needs to get + * them from here too. + * * @return row at current position that being enriched by window function */ @Override @@ -82,11 +75,10 @@ public ExprValue current() { /** * Preload all peer rows if last peer rows done. Note that when no more data in peeking iterator, * there must be rows in frame (hasNext()=true), so no need to check it.hasNext() in this method. - * Load until: - * 1. Different peer found (row with different sort key) - * 2. Or new partition (row with different partition key) - * 3. Or no more rows - * @param it rows iterator + * Load until: 1. Different peer found (row with different sort key) 2. Or new partition (row with + * different partition key) 3. Or no more rows + * + * @param it rows iterator */ @Override public void load(PeekingIterator it) { @@ -118,10 +110,7 @@ public boolean isNewPartition() { private boolean isPeer(ExprValue next) { List sortFields = - windowDefinition.getSortList() - .stream() - .map(Pair::getRight) - .collect(Collectors.toList()); + windowDefinition.getSortList().stream().map(Pair::getRight).collect(Collectors.toList()); ExprValue last = peers.get(peers.size() - 1); return resolve(sortFields, last).equals(resolve(sortFields, next)); @@ -139,9 +128,6 @@ private boolean isSamePartition(ExprValue next) { private List resolve(List expressions, ExprValue row) { Environment valueEnv = row.bindingTuples(); - return expressions.stream() - .map(expr -> expr.valueOf(valueEnv)) - .collect(Collectors.toList()); + return expressions.stream().map(expr -> expr.valueOf(valueEnv)).collect(Collectors.toList()); } - } diff --git a/core/src/main/java/org/opensearch/sql/expression/window/frame/WindowFrame.java b/core/src/main/java/org/opensearch/sql/expression/window/frame/WindowFrame.java index 323656547f..85bc937969 100644 --- a/core/src/main/java/org/opensearch/sql/expression/window/frame/WindowFrame.java +++ b/core/src/main/java/org/opensearch/sql/expression/window/frame/WindowFrame.java @@ -3,7 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ - package org.opensearch.sql.expression.window.frame; import com.google.common.collect.PeekingIterator; @@ -14,13 +13,12 @@ import org.opensearch.sql.expression.env.Environment; /** - * Window frame that represents a subset of a window which is all data accessible to - * the window function when calculation. Basically there are 3 types of window frame: - * 1) Entire window frame that holds all data of the window - * 2) Cumulative window frame that accumulates one row by another - * 3) Sliding window frame that maintains a sliding window of fixed size - * Note that which type of window frame is used is determined by both window function itself - * and frame definition in a window definition. + * Window frame that represents a subset of a window which is all data accessible to the window + * function when calculation. Basically there are 3 types of window frame: 1) Entire window frame + * that holds all data of the window 2) Cumulative window frame that accumulates one row by another + * 3) Sliding window frame that maintains a sliding window of fixed size Note that which type of + * window frame is used is determined by both window function itself and frame definition in a + * window definition. */ public interface WindowFrame extends Environment, Iterator> { @@ -31,20 +29,22 @@ default ExprValue resolve(Expression var) { /** * Check is current row the beginning of a new partition according to window definition. - * @return true if a new partition begins here, otherwise false. + * + * @return true if a new partition begins here, otherwise false. */ boolean isNewPartition(); /** * Load one or more rows as window function calculation needed. - * @param iterator peeking iterator that can peek next element without moving iterator + * + * @param iterator peeking iterator that can peek next element without moving iterator */ void load(PeekingIterator iterator); /** * Get current data row for giving window operator chance to get rows preloaded into frame. + * * @return data row */ ExprValue current(); - } diff --git a/core/src/main/java/org/opensearch/sql/expression/window/ranking/DenseRankFunction.java b/core/src/main/java/org/opensearch/sql/expression/window/ranking/DenseRankFunction.java index ba6e88d98d..87506ef63e 100644 --- a/core/src/main/java/org/opensearch/sql/expression/window/ranking/DenseRankFunction.java +++ b/core/src/main/java/org/opensearch/sql/expression/window/ranking/DenseRankFunction.java @@ -3,15 +3,14 @@ * SPDX-License-Identifier: Apache-2.0 */ - package org.opensearch.sql.expression.window.ranking; import org.opensearch.sql.expression.function.BuiltinFunctionName; import org.opensearch.sql.expression.window.frame.CurrentRowWindowFrame; /** - * Dense rank window function that assigns a rank number to each row similarly as - * rank function. The difference is there is no gap between rank number assigned. + * Dense rank window function that assigns a rank number to each row similarly as rank function. The + * difference is there is no gap between rank number assigned. */ public class DenseRankFunction extends RankingWindowFunction { @@ -30,5 +29,4 @@ protected int rank(CurrentRowWindowFrame frame) { } return rank; } - } diff --git a/core/src/main/java/org/opensearch/sql/expression/window/ranking/RankFunction.java b/core/src/main/java/org/opensearch/sql/expression/window/ranking/RankFunction.java index c1f33e6137..f72a28cd9a 100644 --- a/core/src/main/java/org/opensearch/sql/expression/window/ranking/RankFunction.java +++ b/core/src/main/java/org/opensearch/sql/expression/window/ranking/RankFunction.java @@ -3,22 +3,18 @@ * SPDX-License-Identifier: Apache-2.0 */ - package org.opensearch.sql.expression.window.ranking; import org.opensearch.sql.expression.function.BuiltinFunctionName; import org.opensearch.sql.expression.window.frame.CurrentRowWindowFrame; /** - * Rank window function that assigns a rank number to each row based on sort items - * defined in window definition. Use same rank number if sort item values same on - * previous and current row. + * Rank window function that assigns a rank number to each row based on sort items defined in window + * definition. Use same rank number if sort item values same on previous and current row. */ public class RankFunction extends RankingWindowFunction { - /** - * Total number of rows have seen in current partition. - */ + /** Total number of rows have seen in current partition. */ private int total; public RankFunction() { @@ -38,5 +34,4 @@ protected int rank(CurrentRowWindowFrame frame) { } return rank; } - } diff --git a/core/src/main/java/org/opensearch/sql/expression/window/ranking/RankingWindowFunction.java b/core/src/main/java/org/opensearch/sql/expression/window/ranking/RankingWindowFunction.java index 07a4b42dbd..c119629cda 100644 --- a/core/src/main/java/org/opensearch/sql/expression/window/ranking/RankingWindowFunction.java +++ b/core/src/main/java/org/opensearch/sql/expression/window/ranking/RankingWindowFunction.java @@ -3,7 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ - package org.opensearch.sql.expression.window.ranking; import static java.util.Collections.emptyList; @@ -30,11 +29,9 @@ * such as same return type (integer), same argument list (no arg). */ public abstract class RankingWindowFunction extends FunctionExpression - implements WindowFunctionExpression { + implements WindowFunctionExpression { - /** - * Current rank number assigned. - */ + /** Current rank number assigned. */ protected int rank; public RankingWindowFunction(FunctionName functionName) { @@ -58,26 +55,27 @@ public ExprValue valueOf(Environment valueEnv) { /** * Rank logic that sub-class needs to implement. - * @param frame window frame - * @return rank number + * + * @param frame window frame + * @return rank number */ protected abstract int rank(CurrentRowWindowFrame frame); /** * Check sort field to see if current value is different from previous. - * @param frame window frame - * @return true if different, false if same or no sort list defined + * + * @param frame window frame + * @return true if different, false if same or no sort list defined */ protected boolean isSortFieldValueDifferent(CurrentRowWindowFrame frame) { if (isSortItemsNotDefined(frame)) { return false; } - List sortItems = frame.getWindowDefinition() - .getSortList() - .stream() - .map(Pair::getRight) - .collect(Collectors.toList()); + List sortItems = + frame.getWindowDefinition().getSortList().stream() + .map(Pair::getRight) + .collect(Collectors.toList()); List previous = resolve(frame, sortItems, frame.previous()); List current = resolve(frame, sortItems, frame.current()); @@ -90,9 +88,7 @@ private boolean isSortItemsNotDefined(CurrentRowWindowFrame frame) { private List resolve(WindowFrame frame, List expressions, ExprValue row) { BindingTuple valueEnv = row.bindingTuples(); - return expressions.stream() - .map(expr -> expr.valueOf(valueEnv)) - .collect(Collectors.toList()); + return expressions.stream().map(expr -> expr.valueOf(valueEnv)).collect(Collectors.toList()); } @Override diff --git a/core/src/main/java/org/opensearch/sql/expression/window/ranking/RowNumberFunction.java b/core/src/main/java/org/opensearch/sql/expression/window/ranking/RowNumberFunction.java index 067dfa569d..90bb2ed8ff 100644 --- a/core/src/main/java/org/opensearch/sql/expression/window/ranking/RowNumberFunction.java +++ b/core/src/main/java/org/opensearch/sql/expression/window/ranking/RowNumberFunction.java @@ -3,7 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ - package org.opensearch.sql.expression.window.ranking; import org.opensearch.sql.expression.function.BuiltinFunctionName; @@ -25,5 +24,4 @@ protected int rank(CurrentRowWindowFrame frame) { } return rank++; } - } diff --git a/core/src/main/java/org/opensearch/sql/monitor/AlwaysHealthyMonitor.java b/core/src/main/java/org/opensearch/sql/monitor/AlwaysHealthyMonitor.java index 94bb8d6936..84cec4c9c7 100644 --- a/core/src/main/java/org/opensearch/sql/monitor/AlwaysHealthyMonitor.java +++ b/core/src/main/java/org/opensearch/sql/monitor/AlwaysHealthyMonitor.java @@ -3,19 +3,13 @@ * SPDX-License-Identifier: Apache-2.0 */ - package org.opensearch.sql.monitor; -/** - * Always healthy resource monitor. - */ +/** Always healthy resource monitor. */ public class AlwaysHealthyMonitor extends ResourceMonitor { - public static final ResourceMonitor ALWAYS_HEALTHY_MONITOR = - new AlwaysHealthyMonitor(); + public static final ResourceMonitor ALWAYS_HEALTHY_MONITOR = new AlwaysHealthyMonitor(); - /** - * always healthy. - */ + /** always healthy. */ @Override public boolean isHealthy() { return true; diff --git a/core/src/main/java/org/opensearch/sql/monitor/ResourceMonitor.java b/core/src/main/java/org/opensearch/sql/monitor/ResourceMonitor.java index ce76a3f982..bbd1c67a62 100644 --- a/core/src/main/java/org/opensearch/sql/monitor/ResourceMonitor.java +++ b/core/src/main/java/org/opensearch/sql/monitor/ResourceMonitor.java @@ -3,12 +3,11 @@ * SPDX-License-Identifier: Apache-2.0 */ - package org.opensearch.sql.monitor; /** - * The abstract interface of ResourceMonitor. - * When an fault is detected, the circuit breaker is open. + * The abstract interface of ResourceMonitor. When an fault is detected, the circuit breaker is + * open. */ public abstract class ResourceMonitor { /**