Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,19 @@ public O visit(Expression.TimeLiteral expr, C context) throws E {
return visitFallback(expr, context);
}

/**
* Visits a precision time literal.
*
* @param expr the precision time literal
* @param context the visitation context
* @return the visit result
* @throws E if visitation fails
*/
@Override
public O visit(Expression.PrecisionTimeLiteral expr, C context) throws E {
return visitFallback(expr, context);
}

/**
* Visits a date literal.
*
Expand Down
36 changes: 36 additions & 0 deletions core/src/main/java/io/substrait/expression/Expression.java
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,12 @@ public <R, C extends VisitationContext, E extends Throwable> R accept(
}
}

/**
* @deprecated {@link TimestampLiteral} is deprecated in favor of {@link
* PrecisionTimestampLiteral}
*/
@Value.Immutable
@Deprecated
abstract class TimestampLiteral implements Literal {
public abstract long value();

Expand All @@ -291,7 +296,11 @@ public <R, C extends VisitationContext, E extends Throwable> R accept(
}
}

/**
* @deprecated {@link TimeLiteral} is deprecated in favor of {@link PrecisionTimeLiteral}
*/
@Value.Immutable
@Deprecated
abstract class TimeLiteral implements Literal {
public abstract long value();

Expand All @@ -311,6 +320,28 @@ public <R, C extends VisitationContext, E extends Throwable> R accept(
}
}

@Value.Immutable
abstract class PrecisionTimeLiteral implements Literal {
public abstract long value();

public abstract int precision();

@Override
public Type getType() {
return Type.withNullability(nullable()).precisionTimestamp(precision());
}

public static ImmutableExpression.PrecisionTimeLiteral.Builder builder() {
return ImmutableExpression.PrecisionTimeLiteral.builder();
}

@Override
public <R, C extends VisitationContext, E extends Throwable> R accept(
ExpressionVisitor<R, C, E> visitor, C context) throws E {
return visitor.visit(this, context);
}
}

@Value.Immutable
abstract class DateLiteral implements Literal {
public abstract int value();
Expand All @@ -331,7 +362,12 @@ public <R, C extends VisitationContext, E extends Throwable> R accept(
}
}

/**
* @deprecated {@link TimestampTZLiteral} is deprecated in favor of {@link
* PrecisionTimestampTZLiteral}
*/
@Value.Immutable
@Deprecated
abstract class TimestampTZLiteral implements Literal {
public abstract long value();

Expand Down
13 changes: 13 additions & 0 deletions core/src/main/java/io/substrait/expression/ExpressionCreator.java
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,23 @@ public static Expression.DateLiteral date(boolean nullable, int value) {
return Expression.DateLiteral.builder().nullable(nullable).value(value).build();
}

/**
* @deprecated Time is deprecated in favor of PrecisionTime
*/
@Deprecated
public static Expression.TimeLiteral time(boolean nullable, long value) {
return Expression.TimeLiteral.builder().nullable(nullable).value(value).build();
}

public static Expression.PrecisionTimeLiteral precisionTime(
boolean nullable, long value, int precision) {
return Expression.PrecisionTimeLiteral.builder()
.nullable(nullable)
.value(value)
.precision(precision)
.build();
}

/**
* @deprecated Timestamp is deprecated in favor of PrecisionTimestamp
*/
Expand Down
10 changes: 10 additions & 0 deletions core/src/main/java/io/substrait/expression/ExpressionVisitor.java
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,16 @@ public interface ExpressionVisitor<R, C extends VisitationContext, E extends Thr
*/
R visit(Expression.TimeLiteral expr, C context) throws E;

/**
* Visit a precision time literal.
*
* @param expr the precision time literal
* @param context visitation context
* @return visit result
* @throws E on visit failure
*/
R visit(Expression.PrecisionTimeLiteral expr, C context) throws E;

/**
* Visit a date literal.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,20 @@ public Expression visit(
return lit(bldr -> bldr.setNullable(expr.nullable()).setTime(expr.value()));
}

@Override
public Expression visit(
io.substrait.expression.Expression.PrecisionTimeLiteral expr,
EmptyVisitationContext context) {
return lit(
bldr ->
bldr.setNullable(expr.nullable())
.setPrecisionTime(
Expression.Literal.PrecisionTime.newBuilder()
.setValue(expr.value())
.setPrecision(expr.precision())
.build()));
}

@Override
public Expression visit(
io.substrait.expression.Expression.DateLiteral expr, EmptyVisitationContext context) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,11 @@ public Expression.Literal from(io.substrait.proto.Expression.Literal literal) {
return ExpressionCreator.date(literal.getNullable(), literal.getDate());
case TIME:
return ExpressionCreator.time(literal.getNullable(), literal.getTime());
case PRECISION_TIME:
return ExpressionCreator.precisionTime(
literal.getNullable(),
literal.getPrecisionTime().getValue(),
literal.getPrecisionTime().getPrecision());
case INTERVAL_YEAR_TO_MONTH:
return ExpressionCreator.intervalYear(
literal.getNullable(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import static io.substrait.relation.CopyOnWriteUtils.transformList;

import io.substrait.expression.Expression;
import io.substrait.expression.Expression.PrecisionTimeLiteral;
import io.substrait.expression.ExpressionVisitor;
import io.substrait.expression.FieldReference;
import io.substrait.expression.FunctionArg;
Expand Down Expand Up @@ -95,6 +96,12 @@ public Optional<Expression> visit(Expression.TimeLiteral expr, EmptyVisitationCo
return visitLiteral(expr);
}

@Override
public Optional<Expression> visit(PrecisionTimeLiteral expr, EmptyVisitationContext context)
throws E {
return visitLiteral(expr);
}

@Override
public Optional<Expression> visit(Expression.DateLiteral expr, EmptyVisitationContext context)
throws E {
Expand Down
1 change: 1 addition & 0 deletions core/src/main/java/io/substrait/type/Type.java
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ public <R, E extends Throwable> R accept(final TypeVisitor<R, E> typeVisitor) th
}

@Value.Immutable
@Deprecated
abstract class Time implements Type {
public static ImmutableType.Time.Builder builder() {
return ImmutableType.Time.builder();
Expand Down
1 change: 1 addition & 0 deletions core/src/main/java/io/substrait/type/TypeVisitor.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public interface TypeVisitor<R, E extends Throwable> {

R visit(Type.Date type) throws E;

@Deprecated
R visit(Type.Time type) throws E;

@Deprecated
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import io.substrait.expression.Expression.MapLiteral;
import io.substrait.expression.Expression.MultiOrList;
import io.substrait.expression.Expression.NullLiteral;
import io.substrait.expression.Expression.PrecisionTimeLiteral;
import io.substrait.expression.Expression.PrecisionTimestampLiteral;
import io.substrait.expression.Expression.PrecisionTimestampTZLiteral;
import io.substrait.expression.Expression.ScalarFunctionInvocation;
Expand Down Expand Up @@ -112,6 +113,12 @@ public String visit(TimeLiteral expr, EmptyVisitationContext context) throws Run
return "<TimeLiteral " + expr.value() + ">";
}

@Override
public String visit(PrecisionTimeLiteral expr, EmptyVisitationContext context)
throws RuntimeException {
return "<PrecisionTimeLiteral " + expr.value() + ">";
}

@Override
public String visit(DateLiteral expr, EmptyVisitationContext context) throws RuntimeException {
return "<DateLiteral " + expr.value() + ">";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import io.substrait.expression.EnumArg;
import io.substrait.expression.Expression;
import io.substrait.expression.Expression.FailureBehavior;
import io.substrait.expression.Expression.PrecisionTimeLiteral;
import io.substrait.expression.Expression.PrecisionTimestampLiteral;
import io.substrait.expression.Expression.PrecisionTimestampTZLiteral;
import io.substrait.expression.Expression.ScalarSubquery;
Expand Down Expand Up @@ -205,19 +206,48 @@ public RexNode visit(Expression.BinaryLiteral expr, Context context) throws Runt

@Override
public RexNode visit(Expression.TimeLiteral expr, Context context) throws RuntimeException {
// Expression.TimeLiteral is Microseconds
// Construct a TimeString :
// 1. Truncate microseconds to seconds
// 2. Get the fraction seconds in precision of nanoseconds.
// 3. Construct TimeString : seconds + fraction_seconds part.
long microSec = expr.value();
long seconds = TimeUnit.MICROSECONDS.toSeconds(microSec);
int fracSecondsInNano =
(int) (TimeUnit.MICROSECONDS.toNanos(microSec) - TimeUnit.SECONDS.toNanos(seconds));
TimeString timeString =
TimeString.fromMillisOfDay((int) TimeUnit.SECONDS.toMillis(seconds))
.withNanos(fracSecondsInNano);
return rexBuilder.makeLiteral(timeString, typeConverter.toCalcite(typeFactory, expr.getType()));
return rexBuilder.makeLiteral(
createTimeString(expr.value(), 6), typeConverter.toCalcite(typeFactory, expr.getType()));
}

@Override
public RexNode visit(PrecisionTimeLiteral expr, Context context) throws RuntimeException {
return rexBuilder.makeLiteral(
createTimeString(expr.value(), expr.precision()),
typeConverter.toCalcite(typeFactory, expr.getType()));
}

protected TimeString createTimeString(long value, int precision) {
switch (precision) {
case 0:
return TimeString.fromMillisOfDay((int) TimeUnit.SECONDS.toMillis(value));
case 3:
{
long seconds = TimeUnit.MILLISECONDS.toSeconds(value);
int fracSecondsInNano =
(int) (TimeUnit.MILLISECONDS.toNanos(value) - TimeUnit.SECONDS.toNanos(seconds));
return TimeString.fromMillisOfDay((int) TimeUnit.SECONDS.toMillis(seconds))
.withNanos(fracSecondsInNano);
}
case 6:
{
long seconds = TimeUnit.MICROSECONDS.toSeconds(value);
int fracSecondsInNano =
(int) (TimeUnit.MICROSECONDS.toNanos(value) - TimeUnit.SECONDS.toNanos(seconds));
return TimeString.fromMillisOfDay((int) TimeUnit.SECONDS.toMillis(seconds))
.withNanos(fracSecondsInNano);
}
case 9:
{
long seconds = TimeUnit.NANOSECONDS.toSeconds(value);
int fracSecondsInNano = (int) (value - TimeUnit.SECONDS.toNanos(seconds));
return TimeString.fromMillisOfDay((int) TimeUnit.SECONDS.toMillis(seconds))
.withNanos(fracSecondsInNano);
}
default:
throw new UnsupportedOperationException(
String.format("Cannot handle PrecisionTime with precision %d.", precision));
}
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ class IgnoreNullableAndParameters(val typeToMatch: ParameterizedType)

override def visit(`type`: Type.Date): Boolean = typeToMatch.isInstanceOf[Type.Date]

@nowarn
override def visit(`type`: Type.Time): Boolean = typeToMatch.isInstanceOf[Type.Time]

@nowarn
Expand Down