Skip to content

Commit 8dfa701

Browse files
committed
[feat](func) Support CURTIME with precision
1 parent 9e4411d commit 8dfa701

File tree

5 files changed

+99
-6
lines changed

5 files changed

+99
-6
lines changed

be/src/vec/functions/function_date_or_datetime_computation.h

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -838,10 +838,31 @@ struct CurrentTimeImpl {
838838
static Status execute(FunctionContext* context, Block& block, const ColumnNumbers& arguments,
839839
uint32_t result, size_t input_rows_count) {
840840
auto col_to = ColumnTimeV2::create();
841-
VecDateTimeValue dtv;
841+
DateV2Value<DateTimeV2ValueType> dtv;
842842
dtv.from_unixtime(context->state()->timestamp_ms() / 1000,
843843
context->state()->timezone_obj());
844-
auto time = TimeValue::make_time(dtv.hour(), dtv.minute(), dtv.second());
844+
double time;
845+
if (arguments.size() == 1) {
846+
// the precision must be const, which is checked in fe.
847+
const auto* col = assert_cast<const ColumnInt8*>(
848+
block.get_by_position(arguments[0]).column.get());
849+
uint8_t precision = col->get_element(0);
850+
if (precision >= 0 && precision <= 6) {
851+
dtv.from_unixtime(context->state()->timestamp_ms() / 1000,
852+
context->state()->nano_seconds(),
853+
context->state()->timezone_obj(), precision);
854+
time = TimeValue::make_time(dtv.hour(), dtv.minute(), dtv.second(),
855+
dtv.microsecond());
856+
} else {
857+
return Status::InvalidArgument(
858+
"The precision in function CURTIME should be between 0 and 6, but got {}",
859+
precision);
860+
}
861+
} else {
862+
dtv.from_unixtime(context->state()->timestamp_ms() / 1000,
863+
context->state()->timezone_obj());
864+
time = TimeValue::make_time(dtv.hour(), dtv.minute(), dtv.second());
865+
}
845866
col_to->insert_value(time);
846867
block.get_by_position(result).column =
847868
ColumnConst::create(std::move(col_to), input_rows_count);

fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/executable/DateTimeAcquire.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import org.apache.doris.nereids.trees.expressions.literal.DateV2Literal;
2525
import org.apache.doris.nereids.trees.expressions.literal.IntegerLiteral;
2626
import org.apache.doris.nereids.trees.expressions.literal.TimeV2Literal;
27+
import org.apache.doris.nereids.trees.expressions.literal.TinyIntLiteral;
2728
import org.apache.doris.nereids.util.DateUtils;
2829

2930
import java.time.LocalDateTime;
@@ -95,11 +96,21 @@ public static Expression curTime() {
9596
return TimeV2Literal.fromJavaDateType(LocalDateTime.now(DateUtils.getTimeZone()));
9697
}
9798

99+
@ExecFunction(name = "curtime")
100+
public static Expression curTime(TinyIntLiteral precision) {
101+
return TimeV2Literal.fromJavaDateType(LocalDateTime.now(DateUtils.getTimeZone()), precision.getValue());
102+
}
103+
98104
@ExecFunction(name = "current_time")
99105
public static Expression currentTime() {
100106
return TimeV2Literal.fromJavaDateType(LocalDateTime.now(DateUtils.getTimeZone()));
101107
}
102108

109+
@ExecFunction(name = "current_time")
110+
public static Expression currentTime(TinyIntLiteral precision) {
111+
return TimeV2Literal.fromJavaDateType(LocalDateTime.now(DateUtils.getTimeZone()), precision.getValue());
112+
}
113+
103114
/**
104115
* date transformation function: unix_timestamp
105116
*/

fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/CurrentTime.java

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,16 @@
1818
package org.apache.doris.nereids.trees.expressions.functions.scalar;
1919

2020
import org.apache.doris.catalog.FunctionSignature;
21+
import org.apache.doris.nereids.exceptions.AnalysisException;
2122
import org.apache.doris.nereids.trees.expressions.Expression;
2223
import org.apache.doris.nereids.trees.expressions.functions.AlwaysNotNullable;
23-
import org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature;
24+
import org.apache.doris.nereids.trees.expressions.functions.ComputeSignature;
25+
import org.apache.doris.nereids.trees.expressions.functions.ImplicitlyCastableSignature;
26+
import org.apache.doris.nereids.trees.expressions.literal.TinyIntLiteral;
2427
import org.apache.doris.nereids.trees.expressions.shape.LeafExpression;
2528
import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
2629
import org.apache.doris.nereids.types.TimeV2Type;
30+
import org.apache.doris.nereids.types.TinyIntType;
2731

2832
import com.google.common.base.Preconditions;
2933
import com.google.common.collect.ImmutableList;
@@ -34,10 +38,11 @@
3438
* ScalarFunction 'current_time'. This class is generated by GenerateFunction.
3539
*/
3640
public class CurrentTime extends ScalarFunction
37-
implements LeafExpression, ExplicitlyCastableSignature, AlwaysNotNullable {
41+
implements LeafExpression, ImplicitlyCastableSignature, AlwaysNotNullable, ComputeSignature {
3842

3943
public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
40-
FunctionSignature.ret(TimeV2Type.INSTANCE).args()
44+
FunctionSignature.ret(TimeV2Type.INSTANCE).args(),
45+
FunctionSignature.ret(TimeV2Type.INSTANCE).args(TinyIntType.INSTANCE)
4146
);
4247

4348
/**
@@ -47,17 +52,51 @@ public CurrentTime() {
4752
super("current_time");
4853
}
4954

55+
/**
56+
* constructor with 1 argument.
57+
*/
58+
public CurrentTime(Expression arg) {
59+
super("current_time", arg);
60+
}
61+
5062
/** constructor for withChildren and reuse signature */
5163
private CurrentTime(ScalarFunctionParams functionParams) {
5264
super(functionParams);
5365
}
5466

67+
@Override
68+
public FunctionSignature computeSignature(FunctionSignature signature) {
69+
if (arity() == 1 && child(0) instanceof TinyIntLiteral) {
70+
byte precision = ((TinyIntLiteral) child(0)).getValue();
71+
if (precision < 0 || precision > 6) {
72+
throw new IllegalArgumentException("The precision must be between 0 and 6");
73+
}
74+
return FunctionSignature.ret(TimeV2Type.of(precision)).args(TinyIntType.INSTANCE);
75+
}
76+
77+
return super.computeSignature(signature);
78+
}
79+
5580
@Override
5681
public Expression withChildren(List<Expression> children) {
57-
Preconditions.checkArgument(children.isEmpty());
82+
Preconditions.checkArgument(children.isEmpty() || children.size() == 1);
5883
return new CurrentTime(getFunctionParams(children));
5984
}
6085

86+
@Override
87+
public void checkLegalityAfterRewrite() {
88+
if (arity() == 1) {
89+
if (!child(0).isLiteral()) {
90+
throw new AnalysisException("CURTIME only accepts literal as precision.");
91+
}
92+
}
93+
}
94+
95+
@Override
96+
public void checkLegalityBeforeTypeCoercion() {
97+
checkLegalityAfterRewrite();
98+
}
99+
61100
@Override
62101
public List<FunctionSignature> getSignatures() {
63102
return SIGNATURES;

fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/TimeV2Literal.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,18 @@ public static Expression fromJavaDateType(LocalDateTime dateTime) {
301301
return new TimeV2Literal(dateTime.getHour(), dateTime.getMinute(), dateTime.getSecond(), 0, 0, false);
302302
}
303303

304+
/**
305+
* construct with precision
306+
*/
307+
public static Expression fromJavaDateType(LocalDateTime dateTime, int precision) {
308+
if (isDateOutOfRange(dateTime)) {
309+
throw new AnalysisException("datetime out of range" + dateTime.toString());
310+
}
311+
int value = (int) Math.pow(10, TimeV2Type.MAX_SCALE - precision);
312+
return new TimeV2Literal(dateTime.getHour(), dateTime.getMinute(), dateTime.getSecond(),
313+
(dateTime.getNano() / 1000) / value * value, precision, false);
314+
}
315+
304316
public LocalDateTime toJavaDateType() {
305317
return LocalDateTime.of(0, 1, 1, ((int) getHour()), ((int) getMinute()), ((int) getSecond()),
306318
(int) getMicroSecond() * 1000);

regression-test/suites/query_p0/sql_functions/datetime_functions/test_date_function.groovy

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,16 @@ suite("test_date_function") {
226226
// TIME CURTIME()
227227
def curtime_result = sql """ SELECT CURTIME() """
228228
assertTrue(curtime_result[0].size() == 1)
229+
curtime_result = sql """ SELECT CURTIME(3) """
230+
assertTrue(curtime_result[0].size() == 1)
231+
test {
232+
sql """ SELECT CURTIME(114514);"""
233+
exception "Can not find the compatibility function signature: current_time(INT)"
234+
}
235+
test {
236+
sql """ SELECT CURTIME(7); """
237+
exception "The precision must be between 0 and 6"
238+
}
229239

230240
sql """ insert into ${tableName} values ("2010-11-30 23:59:59") """
231241
// DATE_ADD

0 commit comments

Comments
 (0)