diff --git a/common/src/main/java/org/opensearch/sql/common/utils/QueryContext.java b/common/src/main/java/org/opensearch/sql/common/utils/QueryContext.java
index b399123054..ab11029d73 100644
--- a/common/src/main/java/org/opensearch/sql/common/utils/QueryContext.java
+++ b/common/src/main/java/org/opensearch/sql/common/utils/QueryContext.java
@@ -24,11 +24,6 @@ public class QueryContext {
*/
private static final String REQUEST_ID_KEY = "request_id";
- /**
- * Timestamp when SQL plugin started to process current request.
- */
- private static final String REQUEST_PROCESSING_STARTED = "request_processing_started";
-
/**
* Generates a random UUID and adds to the {@link ThreadContext} as the request id.
*
@@ -56,22 +51,6 @@ public static String getRequestId() {
return id;
}
- public static void recordProcessingStarted() {
- ThreadContext.put(REQUEST_PROCESSING_STARTED, LocalDateTime.now().toString());
- }
-
- /**
- * Get recorded previously time indicating when processing started for the current query.
- * @return A LocalDateTime object
- */
- public static LocalDateTime getProcessingStartedTime() {
- if (ThreadContext.containsKey(REQUEST_PROCESSING_STARTED)) {
- return LocalDateTime.parse(ThreadContext.get(REQUEST_PROCESSING_STARTED));
- }
- // This shouldn't happen outside of unit tests
- return LocalDateTime.now();
- }
-
/**
* Wraps a given instance of {@link Runnable} into a new one which gets all the
* entries from current ThreadContext map.
diff --git a/core/src/main/java/org/opensearch/sql/analysis/AnalysisContext.java b/core/src/main/java/org/opensearch/sql/analysis/AnalysisContext.java
index 2d3ee1a52c..f3fd623371 100644
--- a/core/src/main/java/org/opensearch/sql/analysis/AnalysisContext.java
+++ b/core/src/main/java/org/opensearch/sql/analysis/AnalysisContext.java
@@ -7,9 +7,12 @@
package org.opensearch.sql.analysis;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import java.util.Objects;
import lombok.Getter;
+import org.opensearch.sql.expression.Expression;
import org.opensearch.sql.expression.NamedExpression;
/**
@@ -23,13 +26,26 @@ public class AnalysisContext {
@Getter
private final List namedParseExpressions;
+ /**
+ * Storage for values of functions which return a constant value.
+ * We are storing the values there to use it in sequential calls to those functions.
+ * For example, `now` function should the same value during processing a query.
+ */
+ @Getter
+ private final Map constantFunctionValues;
+
public AnalysisContext() {
this(new TypeEnvironment(null));
}
+ /**
+ * Class CTOR.
+ * @param environment Env to set to a new instance.
+ */
public AnalysisContext(TypeEnvironment environment) {
this.environment = environment;
this.namedParseExpressions = new ArrayList<>();
+ this.constantFunctionValues = new HashMap<>();
}
/**
diff --git a/core/src/main/java/org/opensearch/sql/analysis/ExpressionAnalyzer.java b/core/src/main/java/org/opensearch/sql/analysis/ExpressionAnalyzer.java
index 670da5c85c..ef9d73b7f5 100644
--- a/core/src/main/java/org/opensearch/sql/analysis/ExpressionAnalyzer.java
+++ b/core/src/main/java/org/opensearch/sql/analysis/ExpressionAnalyzer.java
@@ -24,6 +24,7 @@
import org.opensearch.sql.ast.expression.Case;
import org.opensearch.sql.ast.expression.Cast;
import org.opensearch.sql.ast.expression.Compare;
+import org.opensearch.sql.ast.expression.ConstantFunction;
import org.opensearch.sql.ast.expression.EqualTo;
import org.opensearch.sql.ast.expression.Field;
import org.opensearch.sql.ast.expression.Function;
@@ -169,6 +170,19 @@ public Expression visitRelevanceFieldList(RelevanceFieldList node, AnalysisConte
ImmutableMap.copyOf(node.getFieldList())));
}
+ @Override
+ public Expression visitConstantFunction(ConstantFunction node, AnalysisContext context) {
+ var valueName = node.getFuncName();
+ if (context.getConstantFunctionValues().containsKey(valueName)) {
+ return context.getConstantFunctionValues().get(valueName);
+ }
+
+ var value = visitFunction(node, context);
+ value = DSL.literal(value.valueOf(null));
+ context.getConstantFunctionValues().put(valueName, value);
+ return value;
+ }
+
@Override
public Expression visitFunction(Function node, AnalysisContext context) {
FunctionName functionName = FunctionName.of(node.getFuncName());
diff --git a/core/src/main/java/org/opensearch/sql/ast/AbstractNodeVisitor.java b/core/src/main/java/org/opensearch/sql/ast/AbstractNodeVisitor.java
index 17321bc473..e75f8f4ce5 100644
--- a/core/src/main/java/org/opensearch/sql/ast/AbstractNodeVisitor.java
+++ b/core/src/main/java/org/opensearch/sql/ast/AbstractNodeVisitor.java
@@ -15,6 +15,7 @@
import org.opensearch.sql.ast.expression.Case;
import org.opensearch.sql.ast.expression.Cast;
import org.opensearch.sql.ast.expression.Compare;
+import org.opensearch.sql.ast.expression.ConstantFunction;
import org.opensearch.sql.ast.expression.EqualTo;
import org.opensearch.sql.ast.expression.Field;
import org.opensearch.sql.ast.expression.Function;
@@ -116,6 +117,10 @@ public T visitRelevanceFieldList(RelevanceFieldList node, C context) {
return visitChildren(node, context);
}
+ public T visitConstantFunction(ConstantFunction node, C context) {
+ return visitChildren(node, context);
+ }
+
public T visitUnresolvedAttribute(UnresolvedAttribute node, C context) {
return visitChildren(node, context);
}
diff --git a/core/src/main/java/org/opensearch/sql/ast/dsl/AstDSL.java b/core/src/main/java/org/opensearch/sql/ast/dsl/AstDSL.java
index 99d8aaa882..c13dc53ea3 100644
--- a/core/src/main/java/org/opensearch/sql/ast/dsl/AstDSL.java
+++ b/core/src/main/java/org/opensearch/sql/ast/dsl/AstDSL.java
@@ -19,6 +19,7 @@
import org.opensearch.sql.ast.expression.Case;
import org.opensearch.sql.ast.expression.Cast;
import org.opensearch.sql.ast.expression.Compare;
+import org.opensearch.sql.ast.expression.ConstantFunction;
import org.opensearch.sql.ast.expression.DataType;
import org.opensearch.sql.ast.expression.EqualTo;
import org.opensearch.sql.ast.expression.Field;
@@ -234,6 +235,10 @@ public static Function function(String funcName, UnresolvedExpression... funcArg
return new Function(funcName, Arrays.asList(funcArgs));
}
+ public static Function constantFunction(String funcName, UnresolvedExpression... funcArgs) {
+ return new ConstantFunction(funcName, Arrays.asList(funcArgs));
+ }
+
/**
* CASE
* WHEN search_condition THEN result_expr
diff --git a/core/src/main/java/org/opensearch/sql/ast/expression/ConstantFunction.java b/core/src/main/java/org/opensearch/sql/ast/expression/ConstantFunction.java
new file mode 100644
index 0000000000..f14e65eeb2
--- /dev/null
+++ b/core/src/main/java/org/opensearch/sql/ast/expression/ConstantFunction.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+
+package org.opensearch.sql.ast.expression;
+
+import java.util.List;
+import lombok.EqualsAndHashCode;
+import org.opensearch.sql.ast.AbstractNodeVisitor;
+
+/**
+ * Expression node that holds a function which should be replaced by its constant[1] value.
+ * [1] Constant at execution time.
+ */
+@EqualsAndHashCode(callSuper = false)
+public class ConstantFunction extends Function {
+
+ public ConstantFunction(String funcName, List funcArgs) {
+ super(funcName, funcArgs);
+ }
+
+ @Override
+ public R accept(AbstractNodeVisitor nodeVisitor, C context) {
+ return nodeVisitor.visitConstantFunction(this, context);
+ }
+}
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 228fd5ed71..d8dc7fc85f 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
@@ -28,10 +28,8 @@
import java.time.format.TextStyle;
import java.util.Locale;
import java.util.concurrent.TimeUnit;
-import java.util.function.Supplier;
import javax.annotation.Nullable;
import lombok.experimental.UtilityClass;
-import org.opensearch.sql.common.utils.QueryContext;
import org.opensearch.sql.data.model.ExprDateValue;
import org.opensearch.sql.data.model.ExprDatetimeValue;
import org.opensearch.sql.data.model.ExprIntegerValue;
@@ -105,15 +103,12 @@ public void register(BuiltinFunctionRepository repository) {
/**
* NOW() returns a constant time that indicates the time at which the statement began to execute.
+ * `fsp` argument support is removed until refactoring to avoid bug where `now()`, `now(x)` and
+ * `now(y) return different values.
*/
- private LocalDateTime now(@Nullable Integer fsp) {
- return formatLocalDateTime(QueryContext::getProcessingStartedTime, fsp);
- }
-
private FunctionResolver now(FunctionName functionName) {
return define(functionName,
- impl(() -> new ExprDatetimeValue(now((Integer)null)), DATETIME),
- impl((v) -> new ExprDatetimeValue(now(v.integerValue())), DATETIME, INTEGER)
+ impl(() -> new ExprDatetimeValue(formatNow(null)), DATETIME)
);
}
@@ -136,21 +131,19 @@ private FunctionResolver localtime() {
/**
* SYSDATE() returns the time at which it executes.
*/
- private LocalDateTime sysDate(@Nullable Integer fsp) {
- return formatLocalDateTime(LocalDateTime::now, fsp);
- }
-
private FunctionResolver sysdate() {
return define(BuiltinFunctionName.SYSDATE.getName(),
- impl(() -> new ExprDatetimeValue(sysDate(null)), DATETIME),
- impl((v) -> new ExprDatetimeValue(sysDate(v.integerValue())), DATETIME, INTEGER)
+ impl(() -> new ExprDatetimeValue(formatNow(null)), DATETIME),
+ impl((v) -> new ExprDatetimeValue(formatNow(v.integerValue())), DATETIME, INTEGER)
);
}
+ /**
+ * Synonym for @see `now`.
+ */
private FunctionResolver curtime(FunctionName functionName) {
return define(functionName,
- impl(() -> new ExprTimeValue(sysDate(null).toLocalTime()), TIME),
- impl((v) -> new ExprTimeValue(sysDate(v.integerValue()).toLocalTime()), TIME, INTEGER)
+ impl(() -> new ExprTimeValue(formatNow(null).toLocalTime()), TIME)
);
}
@@ -164,7 +157,7 @@ private FunctionResolver current_time() {
private FunctionResolver curdate(FunctionName functionName) {
return define(functionName,
- impl(() -> new ExprDateValue(sysDate(null).toLocalDate()), DATE)
+ impl(() -> new ExprDateValue(formatNow(null).toLocalDate()), DATE)
);
}
@@ -832,17 +825,15 @@ private ExprValue exprYear(ExprValue date) {
}
/**
- * Prepare LocalDateTime value.
- * @param supplier A function which returns LocalDateTime to format.
+ * 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.
* @return LocalDateTime object.
*/
- private LocalDateTime formatLocalDateTime(Supplier supplier,
- @Nullable Integer fsp) {
- var res = supplier.get();
+ private LocalDateTime formatNow(@Nullable Integer fsp) {
+ var res = LocalDateTime.now();
if (fsp == null) {
- return res;
+ fsp = 0;
}
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]
diff --git a/core/src/test/java/org/opensearch/sql/analysis/ExpressionAnalyzerTest.java b/core/src/test/java/org/opensearch/sql/analysis/ExpressionAnalyzerTest.java
index 5a9052f3e4..e3b1ac7e6a 100644
--- a/core/src/test/java/org/opensearch/sql/analysis/ExpressionAnalyzerTest.java
+++ b/core/src/test/java/org/opensearch/sql/analysis/ExpressionAnalyzerTest.java
@@ -8,7 +8,9 @@
import static java.util.Collections.emptyList;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.opensearch.sql.ast.dsl.AstDSL.field;
import static org.opensearch.sql.ast.dsl.AstDSL.floatLiteral;
import static org.opensearch.sql.ast.dsl.AstDSL.function;
@@ -27,14 +29,10 @@
import com.google.common.collect.ImmutableMap;
import java.util.Collections;
import java.util.LinkedHashMap;
+import java.util.List;
import java.util.Map;
-import java.util.function.Function;
-import java.util.stream.Stream;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
-import org.junit.jupiter.params.ParameterizedTest;
-import org.junit.jupiter.params.provider.Arguments;
-import org.junit.jupiter.params.provider.MethodSource;
import org.opensearch.sql.analysis.symbol.Namespace;
import org.opensearch.sql.analysis.symbol.Symbol;
import org.opensearch.sql.ast.dsl.AstDSL;
@@ -53,6 +51,7 @@
import org.opensearch.sql.expression.Expression;
import org.opensearch.sql.expression.FunctionExpression;
import org.opensearch.sql.expression.HighlightExpression;
+import org.opensearch.sql.expression.LiteralExpression;
import org.opensearch.sql.expression.config.ExpressionConfig;
import org.opensearch.sql.expression.window.aggregation.AggregateWindowFunction;
import org.springframework.context.annotation.Configuration;
@@ -552,47 +551,45 @@ public void match_phrase_prefix_all_params() {
);
}
- private static Stream functionNames() {
- var dsl = new DSL(new ExpressionConfig().functionRepository());
- return Stream.of(
- Arguments.of((Function)dsl::now,
- "now", true),
- Arguments.of((Function)dsl::current_timestamp,
- "current_timestamp", true),
- Arguments.of((Function)dsl::localtimestamp,
- "localtimestamp", true),
- Arguments.of((Function)dsl::localtime,
- "localtime", true),
- Arguments.of((Function)dsl::sysdate,
- "sysdate", true),
- Arguments.of((Function)dsl::curtime,
- "curtime", true),
- Arguments.of((Function)dsl::current_time,
- "current_time", true),
- Arguments.of((Function)dsl::curdate,
- "curdate", false),
- Arguments.of((Function)dsl::current_date,
- "current_date", false));
- }
-
- @ParameterizedTest(name = "{1}")
- @MethodSource("functionNames")
- public void now_like_functions(Function function,
- String name,
- Boolean hasFsp) {
- assertAnalyzeEqual(
- function.apply(new Expression[]{}),
- AstDSL.function(name));
-
- if (hasFsp) {
- assertAnalyzeEqual(
- function.apply(new Expression[]{DSL.ref("integer_value", INTEGER)}),
- AstDSL.function(name, field("integer_value")));
-
- assertAnalyzeEqual(
- function.apply(new Expression[]{DSL.literal(3)}),
- AstDSL.function(name, intLiteral(3)));
- }
+ @Test
+ public void constant_function_is_calculated_on_analyze() {
+ // Actually, we can call any function as ConstantFunction to be calculated on analyze stage
+ assertTrue(analyze(AstDSL.constantFunction("now")) instanceof LiteralExpression);
+ assertTrue(analyze(AstDSL.constantFunction("localtime")) instanceof LiteralExpression);
+ }
+
+ @Test
+ public void function_isnt_calculated_on_analyze() {
+ assertTrue(analyze(function("now")) instanceof FunctionExpression);
+ assertTrue(analyze(AstDSL.function("localtime")) instanceof FunctionExpression);
+ }
+
+ @Test
+ public void constant_function_returns_constant_cached_value() {
+ var values = List.of(analyze(AstDSL.constantFunction("now")),
+ analyze(AstDSL.constantFunction("now")), analyze(AstDSL.constantFunction("now")));
+ assertTrue(values.stream().allMatch(v ->
+ v.valueOf(null) == analyze(AstDSL.constantFunction("now")).valueOf(null)));
+ }
+
+ @Test
+ public void function_returns_non_constant_value() {
+ // Even a function returns the same values - they are calculated on each call
+ // `sysdate()` which returns `LocalDateTime.now()` shouldn't be cached and should return always
+ // different values
+ var values = List.of(analyze(function("sysdate")), analyze(function("sysdate")),
+ analyze(function("sysdate")), analyze(function("sysdate")));
+ var referenceValue = analyze(function("sysdate")).valueOf(null);
+ assertTrue(values.stream().noneMatch(v -> v.valueOf(null) == referenceValue));
+ }
+
+ @Test
+ public void now_as_a_function_not_cached() {
+ // // We can call `now()` as a function, in that case nothing should be cached
+ var values = List.of(analyze(function("now")), analyze(function("now")),
+ analyze(function("now")), analyze(function("now")));
+ var referenceValue = analyze(function("now")).valueOf(null);
+ assertTrue(values.stream().noneMatch(v -> v.valueOf(null) == referenceValue));
}
@Test
diff --git a/core/src/test/java/org/opensearch/sql/expression/datetime/NowLikeFunctionTest.java b/core/src/test/java/org/opensearch/sql/expression/datetime/NowLikeFunctionTest.java
index 76a7e4be46..e8f5c16025 100644
--- a/core/src/test/java/org/opensearch/sql/expression/datetime/NowLikeFunctionTest.java
+++ b/core/src/test/java/org/opensearch/sql/expression/datetime/NowLikeFunctionTest.java
@@ -39,19 +39,19 @@ private static Stream functionNames() {
var dsl = new DSL(new ExpressionConfig().functionRepository());
return Stream.of(
Arguments.of((Function)dsl::now,
- "now", DATETIME, true, (Supplier)LocalDateTime::now),
+ "now", DATETIME, false, (Supplier)LocalDateTime::now),
Arguments.of((Function)dsl::current_timestamp,
- "current_timestamp", DATETIME, true, (Supplier)LocalDateTime::now),
+ "current_timestamp", DATETIME, false, (Supplier)LocalDateTime::now),
Arguments.of((Function)dsl::localtimestamp,
- "localtimestamp", DATETIME, true, (Supplier)LocalDateTime::now),
+ "localtimestamp", DATETIME, false, (Supplier)LocalDateTime::now),
Arguments.of((Function)dsl::localtime,
- "localtime", DATETIME, true, (Supplier)LocalDateTime::now),
+ "localtime", DATETIME, false, (Supplier)LocalDateTime::now),
Arguments.of((Function)dsl::sysdate,
"sysdate", DATETIME, true, (Supplier)LocalDateTime::now),
Arguments.of((Function)dsl::curtime,
- "curtime", TIME, true, (Supplier)LocalTime::now),
+ "curtime", TIME, false, (Supplier)LocalTime::now),
Arguments.of((Function)dsl::current_time,
- "current_time", TIME, true, (Supplier)LocalTime::now),
+ "current_time", TIME, false, (Supplier)LocalTime::now),
Arguments.of((Function)dsl::curdate,
"curdate", DATE, false, (Supplier)LocalDate::now),
Arguments.of((Function)dsl::current_date,
diff --git a/docs/user/dql/functions.rst b/docs/user/dql/functions.rst
index c566b10463..e914803243 100644
--- a/docs/user/dql/functions.rst
+++ b/docs/user/dql/functions.rst
@@ -1385,26 +1385,20 @@ Description
Returns the current date and time as a value in 'YYYY-MM-DD hh:mm:ss.nnnnnn' format. The value is expressed in the cluster time zone.
`NOW()` returns a constant time that indicates the time at which the statement began to execute. This differs from the behavior for `SYSDATE() <#sysdate>`_, which returns the exact time at which it executes.
-If the argument is given, it specifies a fractional seconds precision from 0 to 6, the return value includes a fractional seconds part of that many digits.
-
-Argument type: (optional) INTEGER
Return type: DATETIME
-Specifications:
-
-1. NOW() -> DATETIME
-2. NOW(INTEGER) -> DATETIME
+Specification: NOW() -> DATETIME
Example::
- > SELECT NOW(), NOW(0);
+ > SELECT NOW() as value_1, NOW() as value_2;
fetched rows / total rows = 1/1
- +----------------------------+---------------------+
- | NOW() | NOW(0) |
- |----------------------------+---------------------|
- | 2022-08-02 15:39:05.173069 | 2022-08-02 15:39:05 |
- +----------------------------+---------------------+
+ +----------------------------+----------------------------+
+ | value_1 | value_2 |
+ |----------------------------+----------------------------|
+ | 2022-08-02 15:39:05.173069 | 2022-08-02 15:39:05.173069 |
+ +----------------------------+----------------------------+
CURRENT_TIMESTAMP
@@ -1417,13 +1411,13 @@ Description
Example::
- > SELECT CURRENT_TIMESTAMP(), CURRENT_TIMESTAMP(0), CURRENT_TIMESTAMP;
+ > SELECT CURRENT_TIMESTAMP(), CURRENT_TIMESTAMP;
fetched rows / total rows = 1/1
- +----------------------------+------------------------+----------------------------+
- | CURRENT_TIMESTAMP() | CURRENT_TIMESTAMP(0) | CURRENT_TIMESTAMP |
- |----------------------------+------------------------+----------------------------|
- | 2022-08-02 15:54:19.209361 | 2022-08-02 15:54:19 | 2022-08-02 15:54:19.209361 |
- +----------------------------+------------------------+----------------------------+
+ +----------------------------+----------------------------+
+ | CURRENT_TIMESTAMP() | CURRENT_TIMESTAMP |
+ |----------------------------+----------------------------|
+ | 2022-08-02 15:54:19.209361 | 2022-08-02 15:54:19.209361 |
+ +----------------------------+----------------------------+
LOCALTIMESTAMP
@@ -1436,13 +1430,13 @@ Description
Example::
- > SELECT LOCALTIMESTAMP(), LOCALTIMESTAMP(0), LOCALTIMESTAMP;
+ > SELECT LOCALTIMESTAMP(), LOCALTIMESTAMP;
fetched rows / total rows = 1/1
- +----------------------------+---------------------+----------------------------+
- | LOCALTIMESTAMP() | LOCALTIMESTAMP(0) | LOCALTIMESTAMP |
- |----------------------------+---------------------+----------------------------|
- | 2022-08-02 15:54:19.209361 | 2022-08-02 15:54:19 | 2022-08-02 15:54:19.209361 |
- +----------------------------+---------------------+----------------------------+
+ +----------------------------+----------------------------+
+ | LOCALTIMESTAMP() | LOCALTIMESTAMP |
+ |----------------------------+----------------------------|
+ | 2022-08-02 15:54:19.209361 | 2022-08-02 15:54:19.209361 |
+ +----------------------------+----------------------------+
LOCALTIME
@@ -1455,13 +1449,13 @@ Description
Example::
- > SELECT LOCALTIME(), LOCALTIME(0), LOCALTIME;
+ > SELECT LOCALTIME(), LOCALTIME;
fetched rows / total rows = 1/1
- +----------------------------+---------------------+----------------------------+
- | LOCALTIME() | LOCALTIME(0) | LOCALTIME |
- |----------------------------+---------------------+----------------------------|
- | 2022-08-02 15:54:19.209361 | 2022-08-02 15:54:19 | 2022-08-02 15:54:19.209361 |
- +----------------------------+---------------------+----------------------------+
+ +----------------------------+----------------------------+
+ | LOCALTIME() | LOCALTIME |
+ |----------------------------+----------------------------|
+ | 2022-08-02 15:54:19.209361 | 2022-08-02 15:54:19.209361 |
+ +----------------------------+----------------------------+
SYSDATE
@@ -1472,26 +1466,20 @@ Description
Returns the current date and time as a value in 'YYYY-MM-DD hh:mm:ss.nnnnnn'.
SYSDATE() returns the time at which it executes. This differs from the behavior for `NOW() <#now>`_, which returns a constant time that indicates the time at which the statement began to execute.
-If the argument is given, it specifies a fractional seconds precision from 0 to 6, the return value includes a fractional seconds part of that many digits.
-
-Argument type: (optional) INTEGER
Return type: DATETIME
-Specifications:
-
-1. SYSDATE() -> DATETIME
-2. SYSDATE(INTEGER) -> DATETIME
+Specification: SYSDATE() -> DATETIME
Example::
- > SELECT SYSDATE(), SYSDATE(0);
+ > SELECT SYSDATE() as value_1, SYSDATE() as value_2;
fetched rows / total rows = 1/1
- +----------------------------+---------------------+
- | SYSDATE() | SYSDATE(0) |
- |----------------------------+---------------------|
- | 2022-08-02 15:39:05.173069 | 2022-08-02 15:39:05 |
- +----------------------------+---------------------+
+ +----------------------------+----------------------------+
+ | value_1 | value_2 |
+ |----------------------------+----------------------------|
+ | 2022-08-02 15:39:05.173069 | 2022-08-02 15:39:05.173142 |
+ +----------------------------+----------------------------+
CURTIME
@@ -1501,27 +1489,21 @@ Description
>>>>>>>>>>>
Returns the current time as a value in 'hh:mm:ss.nnnnnn'.
-CURTIME() returns the time at which it executes as `SYSDATE() <#sysdate>`_ does.
-If the argument is given, it specifies a fractional seconds precision from 0 to 6, the return value includes a fractional seconds part of that many digits.
-
-Argument type: (optional) INTEGER
+CURTIME() returns the time at which the statement began to execute as `NOW() <#now>`_ does.
Return type: TIME
-Specifications:
-
-1. CURTIME() -> TIME
-2. CURTIME(INTEGER) -> TIME
+Specification: CURTIME() -> TIME
Example::
- > SELECT CURTIME(), CURTIME(0);
+ > SELECT CURTIME() as value_1, CURTIME() as value_2;
fetched rows / total rows = 1/1
- +-----------------+--------------+
- | CURTIME() | CURTIME(0) |
- |-----------------+--------------|
- | 15:39:05.173069 | 15:39:05 |
- +-----------------+--------------+
+ +-----------------+-----------------+
+ | value_1 | value_2 |
+ |-----------------+-----------------|
+ | 15:39:05.173069 | 15:39:05.173069 |
+ +-----------------+-----------------+
CURRENT_TIME
@@ -1534,13 +1516,13 @@ Description
Example::
- > SELECT CURRENT_TIME(), CURRENT_TIME(0), CURRENT_TIME;
+ > SELECT CURRENT_TIME(), CURRENT_TIME;
fetched rows / total rows = 1/1
- +------------------+-------------------+-----------------+
- | CURRENT_TIME() | CURRENT_TIME(0) | CURRENT_TIME |
- |------------------+-------------------+-----------------|
- | 15:39:05.173069 | 15:39:05 | 15:39:05.173069 |
- +------------------+-------------------+-----------------+
+ +-----------------+-----------------+
+ | CURRENT_TIME() | CURRENT_TIME |
+ |-----------------+-----------------|
+ | 15:39:05.173069 | 15:39:05.173069 |
+ +-----------------+-----------------+
CURDATE
@@ -1551,13 +1533,10 @@ Description
Returns the current time as a value in 'YYYY-MM-DD'.
CURDATE() returns the time at which it executes as `SYSDATE() <#sysdate>`_ does.
-If the argument is given, it specifies a fractional seconds precision from 0 to 6, the return value includes a fractional seconds part of that many digits.
Return type: DATE
-Specifications:
-
-CURDATE() -> DATE
+Specification: CURDATE() -> DATE
Example::
diff --git a/docs/user/ppl/functions/datetime.rst b/docs/user/ppl/functions/datetime.rst
index e7eeb32e8e..dbbc2abe21 100644
--- a/docs/user/ppl/functions/datetime.rst
+++ b/docs/user/ppl/functions/datetime.rst
@@ -554,26 +554,20 @@ Description
Returns the current date and time as a value in 'YYYY-MM-DD hh:mm:ss.nnnnnn' format. The value is expressed in the cluster time zone.
`NOW()` returns a constant time that indicates the time at which the statement began to execute. This differs from the behavior for `SYSDATE() <#sysdate>`_, which returns the exact time at which it executes.
-If the argument is given, it specifies a fractional seconds precision from 0 to 6, the return value includes a fractional seconds part of that many digits.
-
-Argument type: (optional) INTEGER
Return type: DATETIME
-Specifications:
-
-1. NOW() -> DATETIME
-2. NOW(INTEGER) -> DATETIME
+Specification: NOW() -> DATETIME
Example::
- > source=people | eval `NOW()` = NOW(), `NOW(0)` = NOW(0) | fields `NOW()`, `NOW(0)`
+ > source=people | eval `value_1` = NOW(), `value_2` = NOW() | fields `value_1`, `value_2`
fetched rows / total rows = 1/1
- +----------------------------+---------------------+
- | NOW() | NOW(0) |
- |----------------------------+---------------------|
- | 2022-08-02 15:39:05.173069 | 2022-08-02 15:39:05 |
- +----------------------------+---------------------+
+ +----------------------------+----------------------------+
+ | value_1 | value_2 |
+ |----------------------------+----------------------------|
+ | 2022-08-02 15:39:05.173069 | 2022-08-02 15:39:05.173069 |
+ +----------------------------+----------------------------+
CURRENT_TIMESTAMP
@@ -586,13 +580,13 @@ Description
Example::
- > source=people | eval `CURRENT_TIMESTAMP()` = CURRENT_TIMESTAMP(), `CURRENT_TIMESTAMP(0)` = CURRENT_TIMESTAMP(0), `CURRENT_TIMESTAMP` = CURRENT_TIMESTAMP | fields `CURRENT_TIMESTAMP()`, `CURRENT_TIMESTAMP(0)`, `CURRENT_TIMESTAMP`
+ > source=people | eval `CURRENT_TIMESTAMP()` = CURRENT_TIMESTAMP(), `CURRENT_TIMESTAMP` = CURRENT_TIMESTAMP | fields `CURRENT_TIMESTAMP()`, `CURRENT_TIMESTAMP`
fetched rows / total rows = 1/1
- +----------------------------+------------------------+----------------------------+
- | CURRENT_TIMESTAMP() | CURRENT_TIMESTAMP(0) | CURRENT_TIMESTAMP |
- |----------------------------+------------------------+----------------------------|
- | 2022-08-02 15:54:19.209361 | 2022-08-02 15:54:19 | 2022-08-02 15:54:19.209361 |
- +----------------------------+------------------------+----------------------------+
+ +----------------------------+----------------------------+
+ | CURRENT_TIMESTAMP() | CURRENT_TIMESTAMP |
+ |----------------------------+----------------------------|
+ | 2022-08-02 15:54:19.209361 | 2022-08-02 15:54:19.209361 |
+ +----------------------------+----------------------------+
LOCALTIMESTAMP
@@ -605,13 +599,13 @@ Description
Example::
- > source=people | eval `LOCALTIMESTAMP()` = LOCALTIMESTAMP(), `LOCALTIMESTAMP(0)` = LOCALTIMESTAMP(0), `LOCALTIMESTAMP` = LOCALTIMESTAMP | fields `LOCALTIMESTAMP()`, `LOCALTIMESTAMP(0)`, `LOCALTIMESTAMP`
+ > source=people | eval `LOCALTIMESTAMP()` = LOCALTIMESTAMP(), `LOCALTIMESTAMP` = LOCALTIMESTAMP | fields `LOCALTIMESTAMP()`, `LOCALTIMESTAMP`
fetched rows / total rows = 1/1
- +----------------------------+---------------------+----------------------------+
- | LOCALTIMESTAMP() | LOCALTIMESTAMP(0) | LOCALTIMESTAMP |
- |----------------------------+---------------------+----------------------------|
- | 2022-08-02 15:54:19.209361 | 2022-08-02 15:54:19 | 2022-08-02 15:54:19.209361 |
- +----------------------------+---------------------+----------------------------+
+ +----------------------------+----------------------------+
+ | LOCALTIMESTAMP() | LOCALTIMESTAMP |
+ |----------------------------+----------------------------|
+ | 2022-08-02 15:54:19.209361 | 2022-08-02 15:54:19.209361 |
+ +----------------------------+----------------------------+
LOCALTIME
@@ -624,13 +618,13 @@ Description
Example::
- > source=people | eval `LOCALTIME()` = LOCALTIME(), `LOCALTIME(0)` = LOCALTIME(0), `LOCALTIME` = LOCALTIME | fields `LOCALTIME()`, `LOCALTIME(0)`, `LOCALTIME`
+ > source=people | eval `LOCALTIME()` = LOCALTIME(), `LOCALTIME` = LOCALTIME | fields `LOCALTIME()`, `LOCALTIME`
fetched rows / total rows = 1/1
- +----------------------------+---------------------+----------------------------+
- | LOCALTIME() | LOCALTIME(0) | LOCALTIME |
- |----------------------------+---------------------+----------------------------|
- | 2022-08-02 15:54:19.209361 | 2022-08-02 15:54:19 | 2022-08-02 15:54:19.209361 |
- +----------------------------+---------------------+----------------------------+
+ +----------------------------+----------------------------+
+ | LOCALTIME() | LOCALTIME |
+ |----------------------------+----------------------------|
+ | 2022-08-02 15:54:19.209361 | 2022-08-02 15:54:19.209361 |
+ +----------------------------+----------------------------+
SYSDATE
@@ -641,26 +635,20 @@ Description
Returns the current date and time as a value in 'YYYY-MM-DD hh:mm:ss.nnnnnn'.
SYSDATE() returns the time at which it executes. This differs from the behavior for `NOW() <#now>`_, which returns a constant time that indicates the time at which the statement began to execute.
-If the argument is given, it specifies a fractional seconds precision from 0 to 6, the return value includes a fractional seconds part of that many digits.
-
-Argument type: (optional) INTEGER
Return type: DATETIME
-Specifications:
-
-1. SYSDATE() -> DATETIME
-2. SYSDATE(INTEGER) -> DATETIME
+Specification: SYSDATE() -> DATETIME
Example::
- > source=people | eval `SYSDATE()` = SYSDATE(), `SYSDATE(0)` = SYSDATE(0) | fields `SYSDATE()`, `SYSDATE(0)`
+ > source=people | eval `value_1` = SYSDATE(), `value_2` = SYSDATE() | fields `value_1`, `value_2`
fetched rows / total rows = 1/1
- +----------------------------+---------------------+
- | SYSDATE() | SYSDATE(0) |
- |----------------------------+---------------------|
- | 2022-08-02 15:39:05.173069 | 2022-08-02 15:39:05 |
- +----------------------------+---------------------+
+ +----------------------------+----------------------------+
+ | value_1 | value_2 |
+ |----------------------------+----------------------------|
+ | 2022-08-02 15:39:05.173069 | 2022-08-02 15:39:05.173142 |
+ +----------------------------+----------------------------+
CURTIME
@@ -670,27 +658,21 @@ Description
>>>>>>>>>>>
Returns the current time as a value in 'hh:mm:ss.nnnnnn'.
-CURTIME() returns the time at which it executes as `SYSDATE() <#sysdate>`_ does.
-If the argument is given, it specifies a fractional seconds precision from 0 to 6, the return value includes a fractional seconds part of that many digits.
-
-Argument type: (optional) INTEGER
+CURTIME() returns the time at which the statement began to execute as `NOW() <#now>`_ does.
Return type: TIME
-Specifications:
-
-1. CURTIME() -> TIME
-2. CURTIME(INTEGER) -> TIME
+Specification: CURTIME() -> TIME
Example::
- > source=people | eval `CURTIME()` = CURTIME(), `CURTIME(0)` = CURTIME(0) | fields `CURTIME()`, `CURTIME(0)`
+ > source=people | eval `value_1` = CURTIME(), `value_2` = CURTIME() | fields `value_1`, `value_2`
fetched rows / total rows = 1/1
- +-----------------+--------------+
- | CURTIME() | CURTIME(0) |
- |-----------------+--------------|
- | 15:39:05.173069 | 15:39:05 |
- +-----------------+--------------+
+ +-----------------+-----------------+
+ | value_1 | value_2 |
+ |-----------------+-----------------|
+ | 15:39:05.173069 | 15:39:05.173069 |
+ +-----------------+-----------------+
CURRENT_TIME
@@ -703,13 +685,13 @@ Description
Example::
- > source=people | eval `CURRENT_TIME()` = CURRENT_TIME(), `CURRENT_TIME(0)` = CURRENT_TIME(0), `CURRENT_TIME` = CURRENT_TIME | fields `CURRENT_TIME()`, `CURRENT_TIME(0)`, `CURRENT_TIME`
+ > source=people | eval `CURRENT_TIME()` = CURRENT_TIME(), `CURRENT_TIME` = CURRENT_TIME | fields `CURRENT_TIME()`, `CURRENT_TIME`
fetched rows / total rows = 1/1
- +------------------+-------------------+-----------------+
- | CURRENT_TIME() | CURRENT_TIME(0) | CURRENT_TIME |
- |------------------+-------------------+-----------------|
- | 15:39:05.173069 | 15:39:05 | 15:39:05.173069 |
- +------------------+-------------------+-----------------+
+ +------------------+-----------------+
+ | CURRENT_TIME() | CURRENT_TIME |
+ |------------------+-----------------|
+ | 15:39:05.173069 | 15:39:05.173069 |
+ +------------------+-----------------+
CURDATE
@@ -720,13 +702,10 @@ Description
Returns the current time as a value in 'YYYY-MM-DD'.
CURDATE() returns the time at which it executes as `SYSDATE() <#sysdate>`_ does.
-If the argument is given, it specifies a fractional seconds precision from 0 to 6, the return value includes a fractional seconds part of that many digits.
Return type: DATE
-Specifications:
-
-CURDATE() -> DATE
+Specification: CURDATE() -> DATE
Example::
diff --git a/integ-test/src/test/java/org/opensearch/sql/ppl/DateTimeFunctionIT.java b/integ-test/src/test/java/org/opensearch/sql/ppl/DateTimeFunctionIT.java
index 9ba83b63bf..a0b0e8673b 100644
--- a/integ-test/src/test/java/org/opensearch/sql/ppl/DateTimeFunctionIT.java
+++ b/integ-test/src/test/java/org/opensearch/sql/ppl/DateTimeFunctionIT.java
@@ -504,7 +504,7 @@ private List> nowLikeFunctionsData() {
return List.of(
ImmutableMap.builder()
.put("name", "now")
- .put("hasFsp", true)
+ .put("hasFsp", false)
.put("hasShortcut", false)
.put("constValue", true)
.put("referenceGetter", (Supplier) LocalDateTime::now)
@@ -513,7 +513,7 @@ private List> nowLikeFunctionsData() {
.build(),
ImmutableMap.builder()
.put("name", "current_timestamp")
- .put("hasFsp", true)
+ .put("hasFsp", false)
.put("hasShortcut", true)
.put("constValue", true)
.put("referenceGetter", (Supplier) LocalDateTime::now)
@@ -522,7 +522,7 @@ private List> nowLikeFunctionsData() {
.build(),
ImmutableMap.builder()
.put("name", "localtimestamp")
- .put("hasFsp", true)
+ .put("hasFsp", false)
.put("hasShortcut", true)
.put("constValue", true)
.put("referenceGetter", (Supplier) LocalDateTime::now)
@@ -531,7 +531,7 @@ private List> nowLikeFunctionsData() {
.build(),
ImmutableMap.builder()
.put("name", "localtime")
- .put("hasFsp", true)
+ .put("hasFsp", false)
.put("hasShortcut", true)
.put("constValue", true)
.put("referenceGetter", (Supplier) LocalDateTime::now)
@@ -549,7 +549,7 @@ private List> nowLikeFunctionsData() {
.build(),
ImmutableMap.builder()
.put("name", "curtime")
- .put("hasFsp", true)
+ .put("hasFsp", false)
.put("hasShortcut", false)
.put("constValue", false)
.put("referenceGetter", (Supplier) LocalTime::now)
@@ -558,7 +558,7 @@ private List> nowLikeFunctionsData() {
.build(),
ImmutableMap.builder()
.put("name", "current_time")
- .put("hasFsp", true)
+ .put("hasFsp", false)
.put("hasShortcut", true)
.put("constValue", false)
.put("referenceGetter", (Supplier) LocalTime::now)
diff --git a/integ-test/src/test/java/org/opensearch/sql/sql/DateTimeFunctionIT.java b/integ-test/src/test/java/org/opensearch/sql/sql/DateTimeFunctionIT.java
index 7b5b1c70f8..db4bec2540 100644
--- a/integ-test/src/test/java/org/opensearch/sql/sql/DateTimeFunctionIT.java
+++ b/integ-test/src/test/java/org/opensearch/sql/sql/DateTimeFunctionIT.java
@@ -493,7 +493,7 @@ private List> nowLikeFunctionsData() {
return List.of(
ImmutableMap.builder()
.put("name", "now")
- .put("hasFsp", true)
+ .put("hasFsp", false)
.put("hasShortcut", false)
.put("constValue", true)
.put("referenceGetter", (Supplier) LocalDateTime::now)
@@ -502,7 +502,7 @@ private List> nowLikeFunctionsData() {
.build(),
ImmutableMap.builder()
.put("name", "current_timestamp")
- .put("hasFsp", true)
+ .put("hasFsp", false)
.put("hasShortcut", true)
.put("constValue", true)
.put("referenceGetter", (Supplier) LocalDateTime::now)
@@ -511,7 +511,7 @@ private List> nowLikeFunctionsData() {
.build(),
ImmutableMap.builder()
.put("name", "localtimestamp")
- .put("hasFsp", true)
+ .put("hasFsp", false)
.put("hasShortcut", true)
.put("constValue", true)
.put("referenceGetter", (Supplier) LocalDateTime::now)
@@ -520,7 +520,7 @@ private List> nowLikeFunctionsData() {
.build(),
ImmutableMap.builder()
.put("name", "localtime")
- .put("hasFsp", true)
+ .put("hasFsp", false)
.put("hasShortcut", true)
.put("constValue", true)
.put("referenceGetter", (Supplier) LocalDateTime::now)
@@ -538,7 +538,7 @@ private List> nowLikeFunctionsData() {
.build(),
ImmutableMap.builder()
.put("name", "curtime")
- .put("hasFsp", true)
+ .put("hasFsp", false)
.put("hasShortcut", false)
.put("constValue", false)
.put("referenceGetter", (Supplier) LocalTime::now)
@@ -547,7 +547,7 @@ private List> nowLikeFunctionsData() {
.build(),
ImmutableMap.builder()
.put("name", "current_time")
- .put("hasFsp", true)
+ .put("hasFsp", false)
.put("hasShortcut", true)
.put("constValue", false)
.put("referenceGetter", (Supplier) LocalTime::now)
diff --git a/legacy/src/main/java/org/opensearch/sql/legacy/plugin/RestSqlAction.java b/legacy/src/main/java/org/opensearch/sql/legacy/plugin/RestSqlAction.java
index 8c68dbd416..ab146404f8 100644
--- a/legacy/src/main/java/org/opensearch/sql/legacy/plugin/RestSqlAction.java
+++ b/legacy/src/main/java/org/opensearch/sql/legacy/plugin/RestSqlAction.java
@@ -127,7 +127,6 @@ protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient cli
Metrics.getInstance().getNumericalMetric(MetricName.REQ_COUNT_TOTAL).increment();
QueryContext.addRequestId();
- QueryContext.recordProcessingStarted();
try {
if (!isSQLFeatureEnabled()) {
diff --git a/plugin/src/main/java/org/opensearch/sql/plugin/transport/TransportPPLQueryAction.java b/plugin/src/main/java/org/opensearch/sql/plugin/transport/TransportPPLQueryAction.java
index 9f0f57fe3b..eaad009216 100644
--- a/plugin/src/main/java/org/opensearch/sql/plugin/transport/TransportPPLQueryAction.java
+++ b/plugin/src/main/java/org/opensearch/sql/plugin/transport/TransportPPLQueryAction.java
@@ -81,7 +81,6 @@ protected void doExecute(
Metrics.getInstance().getNumericalMetric(MetricName.PPL_REQ_COUNT_TOTAL).increment();
QueryContext.addRequestId();
- QueryContext.recordProcessingStarted();
PPLService pplService = createPPLService(client);
TransportPPLQueryRequest transportRequest = TransportPPLQueryRequest.fromActionRequest(request);
diff --git a/ppl/src/main/antlr/OpenSearchPPLParser.g4 b/ppl/src/main/antlr/OpenSearchPPLParser.g4
index fc15318b65..1bd1140d8a 100644
--- a/ppl/src/main/antlr/OpenSearchPPLParser.g4
+++ b/ppl/src/main/antlr/OpenSearchPPLParser.g4
@@ -221,6 +221,11 @@ primaryExpression
| dataTypeFunctionCall
| fieldExpression
| literalValue
+ | constantFunction
+ ;
+
+constantFunction
+ : constantFunctionName LT_PRTHS functionArgs? RT_PRTHS
;
booleanExpression
@@ -373,11 +378,14 @@ trigonometricFunctionName
;
dateAndTimeFunctionBase
- : ADDDATE | DATE | DATE_ADD | DATE_SUB | DAY | DAYNAME | DAYOFMONTH | DAYOFWEEK | DAYOFYEAR | FROM_DAYS
- | HOUR | MICROSECOND | MINUTE | MONTH | MONTHNAME | QUARTER | SECOND | SUBDATE | TIME | TIME_TO_SEC
- | TIMESTAMP | TO_DAYS | YEAR | WEEK | DATE_FORMAT | NOW | CURDATE | CURRENT_DATE | CURTIME | CURRENT_TIME
- | LOCALTIME | CURRENT_TIMESTAMP | LOCALTIMESTAMP | SYSDATE | UTC_TIMESTAMP | UTC_DATE | UTC_TIME
- | MAKETIME | MAKEDATE
+ : ADDDATE | DATE | DATE_ADD | DATE_FORMAT | DATE_SUB | DAY | DAYNAME | DAYOFMONTH | DAYOFWEEK
+ | DAYOFYEAR | FROM_DAYS | HOUR | MAKEDATE | MAKETIME | MICROSECOND | MINUTE | MONTH | MONTHNAME
+ | QUARTER | SECOND | SUBDATE | SYSDATE | TIME | TIME_TO_SEC| TIMESTAMP | TO_DAYS | WEEK | YEAR
+ ;
+
+constantFunctionName
+ : datetimeConstantLiteral
+ | CURDATE | CURTIME | NOW
;
/** condition function return boolean value */
diff --git a/ppl/src/main/java/org/opensearch/sql/ppl/parser/AstExpressionBuilder.java b/ppl/src/main/java/org/opensearch/sql/ppl/parser/AstExpressionBuilder.java
index c8424aecb4..5df1c4ec56 100644
--- a/ppl/src/main/java/org/opensearch/sql/ppl/parser/AstExpressionBuilder.java
+++ b/ppl/src/main/java/org/opensearch/sql/ppl/parser/AstExpressionBuilder.java
@@ -14,6 +14,7 @@
import static org.opensearch.sql.ppl.antlr.parser.OpenSearchPPLParser.BooleanLiteralContext;
import static org.opensearch.sql.ppl.antlr.parser.OpenSearchPPLParser.BySpanClauseContext;
import static org.opensearch.sql.ppl.antlr.parser.OpenSearchPPLParser.CompareExprContext;
+import static org.opensearch.sql.ppl.antlr.parser.OpenSearchPPLParser.ConstantFunctionContext;
import static org.opensearch.sql.ppl.antlr.parser.OpenSearchPPLParser.ConvertedDataTypeContext;
import static org.opensearch.sql.ppl.antlr.parser.OpenSearchPPLParser.CountAllFunctionCallContext;
import static org.opensearch.sql.ppl.antlr.parser.OpenSearchPPLParser.DataTypeFunctionCallContext;
@@ -61,6 +62,7 @@
import org.opensearch.sql.ast.expression.Argument;
import org.opensearch.sql.ast.expression.Cast;
import org.opensearch.sql.ast.expression.Compare;
+import org.opensearch.sql.ast.expression.ConstantFunction;
import org.opensearch.sql.ast.expression.DataType;
import org.opensearch.sql.ast.expression.Field;
import org.opensearch.sql.ast.expression.Function;
@@ -245,15 +247,29 @@ public UnresolvedExpression visitConvertedDataType(ConvertedDataTypeContext ctx)
@Override
public UnresolvedExpression visitDatetimeConstantLiteral(DatetimeConstantLiteralContext ctx) {
- return visitFunction(ctx.getText(), null);
+ return visitConstantFunction(ctx.getText(), null);
}
- private Function visitFunction(String functionName, FunctionArgsContext args) {
- return new Function(
- functionName,
+ public UnresolvedExpression visitConstantFunction(ConstantFunctionContext ctx) {
+ return visitConstantFunction(ctx.constantFunctionName().getText(),
+ ctx.functionArgs());
+ }
+
+ private UnresolvedExpression visitConstantFunction(String functionName,
+ FunctionArgsContext args) {
+ return new ConstantFunction(functionName,
args == null
? Collections.emptyList()
: args.functionArg()
+ .stream()
+ .map(this::visitFunctionArg)
+ .collect(Collectors.toList()));
+ }
+
+ private Function visitFunction(String functionName, FunctionArgsContext args) {
+ return new Function(
+ functionName,
+ args.functionArg()
.stream()
.map(this::visitFunctionArg)
.collect(Collectors.toList())
diff --git a/ppl/src/test/java/org/opensearch/sql/ppl/parser/AstExpressionBuilderTest.java b/ppl/src/test/java/org/opensearch/sql/ppl/parser/AstExpressionBuilderTest.java
index bb3315d5c8..1becf086ac 100644
--- a/ppl/src/test/java/org/opensearch/sql/ppl/parser/AstExpressionBuilderTest.java
+++ b/ppl/src/test/java/org/opensearch/sql/ppl/parser/AstExpressionBuilderTest.java
@@ -7,6 +7,7 @@
package org.opensearch.sql.ppl.parser;
import static java.util.Collections.emptyList;
+import static org.junit.Assert.assertEquals;
import static org.opensearch.sql.ast.dsl.AstDSL.agg;
import static org.opensearch.sql.ast.dsl.AstDSL.aggregate;
import static org.opensearch.sql.ast.dsl.AstDSL.alias;
@@ -47,11 +48,13 @@
import java.util.Collections;
import org.junit.Ignore;
import org.junit.Test;
+import org.opensearch.sql.ast.Node;
import org.opensearch.sql.ast.expression.AllFields;
import org.opensearch.sql.ast.expression.Argument;
import org.opensearch.sql.ast.expression.DataType;
import org.opensearch.sql.ast.expression.Literal;
import org.opensearch.sql.ast.expression.RelevanceFieldList;
+import org.opensearch.sql.ppl.antlr.PPLSyntaxParser;
public class AstExpressionBuilderTest extends AstBuilderTest {
@@ -168,6 +171,18 @@ public void testEvalFunctionExpr() {
));
}
+ @Test
+ public void testEvalFunctionExprNoArgs() {
+ assertEqual("source=t | eval f=PI()",
+ eval(
+ relation("t"),
+ let(
+ field("f"),
+ function("PI")
+ )
+ ));
+ }
+
@Test
public void testEvalBinaryOperationExpr() {
assertEqual("source=t | eval f=a+b",
@@ -715,4 +730,9 @@ public void canBuildQuery_stringRelevanceFunctionWithArguments() {
)
);
}
+
+ private Node buildExprAst(String query) {
+ AstBuilder astBuilder = new AstBuilder(new AstExpressionBuilder(), query);
+ return astBuilder.visit(new PPLSyntaxParser().parse(query));
+ }
}
diff --git a/ppl/src/test/java/org/opensearch/sql/ppl/parser/AstNowLikeFunctionTest.java b/ppl/src/test/java/org/opensearch/sql/ppl/parser/AstNowLikeFunctionTest.java
index feb06b996b..6c6233a17f 100644
--- a/ppl/src/test/java/org/opensearch/sql/ppl/parser/AstNowLikeFunctionTest.java
+++ b/ppl/src/test/java/org/opensearch/sql/ppl/parser/AstNowLikeFunctionTest.java
@@ -8,6 +8,7 @@
import static org.junit.Assert.assertEquals;
import static org.opensearch.sql.ast.dsl.AstDSL.compare;
+import static org.opensearch.sql.ast.dsl.AstDSL.constantFunction;
import static org.opensearch.sql.ast.dsl.AstDSL.eval;
import static org.opensearch.sql.ast.dsl.AstDSL.field;
import static org.opensearch.sql.ast.dsl.AstDSL.filter;
@@ -33,11 +34,14 @@ public class AstNowLikeFunctionTest {
* @param name Function name
* @param hasFsp Whether function has fsp argument
* @param hasShortcut Whether function has shortcut (call without `()`)
+ * @param isConstantFunction Whether function has constant value
*/
- public AstNowLikeFunctionTest(String name, Boolean hasFsp, Boolean hasShortcut) {
+ public AstNowLikeFunctionTest(String name, Boolean hasFsp, Boolean hasShortcut,
+ Boolean isConstantFunction) {
this.name = name;
this.hasFsp = hasFsp;
this.hasShortcut = hasShortcut;
+ this.isConstantFunction = isConstantFunction;
}
/**
@@ -47,21 +51,22 @@ public AstNowLikeFunctionTest(String name, Boolean hasFsp, Boolean hasShortcut)
@Parameterized.Parameters(name = "{0}")
public static Iterable