Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature](literal)Support TimeLiteral #47319

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions fe/fe-common/src/main/java/org/apache/doris/catalog/Type.java
Original file line number Diff line number Diff line change
Expand Up @@ -672,6 +672,10 @@ public boolean isTime() {
return isScalarType(PrimitiveType.TIME);
}

public boolean isTimeType() {
return isTime() || isTimeV2();
}

public boolean isComplexType() {
return isStructType() || isCollectionType();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -465,6 +465,8 @@ private Expr castTo(LiteralExpr value) throws AnalysisException {
return new StringLiteral(value.getStringValue()).convertToDate(type);
} else if (type.isBoolean()) {
return new BoolLiteral(value.getStringValue());
} else if (type.isTimeType()) {
return new TimeLiteral(value.getStringValue());
}
return this;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,9 @@ public static LiteralExpr create(String value, Type type) throws AnalysisExcepti
case IPV6:
literalExpr = new IPv6Literal(value);
break;
case TIME:
literalExpr = new TimeLiteral(value);
break;
default:
throw new AnalysisException("Type[" + type.toSql() + "] not supported.");
}
Expand Down Expand Up @@ -169,6 +172,8 @@ public static LiteralExpr init(LiteralExpr expr) throws AnalysisException {
literalExpr = new JsonLiteral(value);
} else if (expr instanceof DateLiteral) {
literalExpr = new DateLiteral(value, expr.getType());
} else if (expr instanceof TimeLiteral) {
literalExpr = new TimeLiteral(value);
} else {
throw new AnalysisException("Type[" + expr.getType().toSql() + "] not supported.");
}
Expand Down
158 changes: 158 additions & 0 deletions fe/fe-core/src/main/java/org/apache/doris/analysis/TimeLiteral.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.

package org.apache.doris.analysis;

import org.apache.doris.common.FormatOptions;
import org.apache.doris.nereids.exceptions.AnalysisException;
import org.apache.doris.thrift.TExprNode;
import org.apache.doris.thrift.TExprNodeType;
import org.apache.doris.thrift.TTimeLiteral;

public class TimeLiteral extends LiteralExpr {

public static final TimeLiteral MIN_TIME = new TimeLiteral(-838, 0, 0);
public static final TimeLiteral MAX_TIME = new TimeLiteral(838, 59, 59);

protected long hour;
protected long minute;
protected long second;

/**
* C'tor forcing type, e.g., due to implicit cast
*/
// for restore
private TimeLiteral() {
this.hour = 0;
this.minute = 0;
this.second = 0;
}

public TimeLiteral(long hour, long minute, long second) {
super();
this.hour = hour;
this.minute = minute;
this.second = second;
analysisDone();
}

public TimeLiteral(String s) throws AnalysisException {
super();
init(s);
analysisDone();
}

protected TimeLiteral(TimeLiteral other) {
super(other);
this.hour = other.getHour();
this.minute = other.getMinute();
this.second = other.getSecond();
}

@Override
public Expr clone() {
return new TimeLiteral(this);
}

protected void init(String s) throws AnalysisException {
if (s.length() == 8) {
hour = readNextInt(s, 0, 2);
minute = readNextInt(s, 3, 2);
second = readNextInt(s, 6, 2);
} else if (s.length() == 9) {
hour = readNextInt(s, 0, 3);
minute = readNextInt(s, 4, 2);
second = readNextInt(s, 7, 2);
} else {
hour = minute = second = -1;
}

if (checkRange(hour, minute, second)) {
throw new AnalysisException("time literal [" + s + "] is out of range");
}
}

@Override
protected String toSqlImpl() {
return "\"" + getStringValue() + "\"";
}

@Override
protected void toThrift(TExprNode msg) {
msg.node_type = TExprNodeType.TIME_LITERAL;
msg.time_literal = new TTimeLiteral(getStringValue());
}

@Override
public boolean isMinValue() {
return hour == MIN_TIME.getHour() && minute == MIN_TIME.getMinute() && second == MIN_TIME.getSecond();
}

@Override
public int compareLiteral(LiteralExpr expr) {
return 0;
}

@Override
public String getStringValue() {
long h = Math.max(Math.min(hour, MAX_TIME.getHour()), MIN_TIME.getHour());
long m = Math.max(Math.min(minute, MAX_TIME.getMinute()), MIN_TIME.getMinute());
long s = Math.max(Math.min(second, MAX_TIME.getSecond()), MIN_TIME.getSecond());

if (h > 99) {
return String.format("%03d:%02d:%02d", h, m, s);
}
return String.format("%02d:%02d:%02d", h, m, s);
}

@Override
public String getStringValueForArray(FormatOptions options) {
return options.getNestedStringWrapper() + getStringValue() + options.getNestedStringWrapper();
}

protected static boolean checkRange(long hour, long minute, long second) {
return hour > MAX_TIME.getHour() || minute > MAX_TIME.getMinute() || second > MAX_TIME.getSecond()
|| hour < MIN_TIME.getHour() || minute < MIN_TIME.getMinute() || second < MIN_TIME.getSecond();
}

public long getHour() {
return hour;
}

public long getMinute() {
return minute;
}

public long getSecond() {
return second;
}

private static Integer readNextInt(String str, int offset, int readLength) {
int value = 0;
int realReadLength = 0;
for (int i = offset; i < str.length(); i++) {
char c = str.charAt(i);
if ('0' <= c && c <= '9') {
realReadLength++;
value = value * 10 + (c - '0');
} else {
break;
}
}
return readLength == realReadLength ? value : null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import org.apache.doris.nereids.trees.expressions.literal.DateTimeLiteral;
import org.apache.doris.nereids.trees.expressions.literal.DateTimeV2Literal;
import org.apache.doris.nereids.trees.expressions.literal.IntegerLiteral;
import org.apache.doris.nereids.trees.expressions.literal.TimeLiteral;
import org.apache.doris.nereids.util.DateUtils;

import java.time.LocalDateTime;
Expand Down Expand Up @@ -86,19 +87,18 @@ public static Expression currentDate() {
return DateLiteral.fromJavaDateType(LocalDateTime.now(DateUtils.getTimeZone()));
}

// comment these function temporally until we support TimeLiteral
// /**
// * date acquire function: current_time
// */
// @ExecFunction(name = "curtime")
// public static Expression curTime() {
// return DateTimeLiteral.fromJavaDateType(LocalDateTime.now(DateUtils.getTimeZone()));
// }
/**
* date acquire function: current_time
*/
@ExecFunction(name = "curtime")
public static Expression curTime() {
return TimeLiteral.fromJavaDateType(LocalDateTime.now(DateUtils.getTimeZone()));
}

// @ExecFunction(name = "current_time")
// public static Expression currentTime() {
// return DateTimeLiteral.fromJavaDateType(LocalDateTime.now(DateUtils.getTimeZone()));
// }
@ExecFunction(name = "current_time")
public static Expression currentTime() {
return TimeLiteral.fromJavaDateType(LocalDateTime.now(DateUtils.getTimeZone()));
}

/**
* date transformation function: unix_timestamp
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,8 @@ protected Expression uncheckedCastTo(DataType targetType) throws AnalysisExcepti
return new IPv4Literal(desc);
} else if (targetType.isIPv6Type()) {
return new IPv6Literal(desc);
} else if (targetType.isTimeType()) {
return new TimeLiteral(desc);
}
throw new AnalysisException("cannot cast " + desc + " from type " + this.dataType + " to type " + targetType);
}
Expand Down
Loading
Loading