Skip to content

Commit

Permalink
[CALCITE-1829] Add TIME/TIMESTAMP/DATE datatype handling to RexImplic…
Browse files Browse the repository at this point in the history
…ationChecker

Close apache#467
  • Loading branch information
minji-kim authored and julianhyde committed Jun 6, 2017
1 parent 91d9576 commit 419b810
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 58 deletions.
63 changes: 18 additions & 45 deletions core/src/main/java/org/apache/calcite/plan/VisitorDataContext.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,6 @@
import org.slf4j.LoggerFactory;

import java.math.BigDecimal;
import java.sql.Date;
import java.util.Calendar;
import java.util.List;

/**
Expand Down Expand Up @@ -116,7 +114,7 @@ public static DataContext of(RelDataType rowType,
if (inputRef instanceof RexInputRef
&& literal instanceof RexLiteral) {
final int index = ((RexInputRef) inputRef).getIndex();
Object value = ((RexLiteral) literal).getValue();
final RexLiteral rexLiteral = (RexLiteral) literal;
final RelDataType type = inputRef.getType();

if (type.getSqlTypeName() == null) {
Expand All @@ -126,61 +124,36 @@ public static DataContext of(RelDataType rowType,

switch (type.getSqlTypeName()) {
case INTEGER:
if (value instanceof BigDecimal) {
return Pair.of(index, ((BigDecimal) value).intValue());
}
return Pair.of(index, rexLiteral.getValueAs(Integer.class));
case DOUBLE:
if (value instanceof BigDecimal) {
return Pair.of(index, ((BigDecimal) value).doubleValue());
}
return Pair.of(index, rexLiteral.getValueAs(Double.class));
case REAL:
if (value instanceof BigDecimal) {
return Pair.of(index, ((BigDecimal) value).floatValue());
}
return Pair.of(index, rexLiteral.getValueAs(Float.class));
case BIGINT:
if (value instanceof BigDecimal) {
return Pair.of(index, ((BigDecimal) value).longValue());
}
return Pair.of(index, rexLiteral.getValueAs(Long.class));
case SMALLINT:
if (value instanceof BigDecimal) {
return Pair.of(index, ((BigDecimal) value).shortValue());
}
return Pair.of(index, rexLiteral.getValueAs(Short.class));
case TINYINT:
if (value instanceof BigDecimal) {
return Pair.of(index, (short) ((BigDecimal) value).byteValue());
}
return Pair.of(index, rexLiteral.getValueAs(Byte.class));
case DECIMAL:
if (value instanceof BigDecimal) {
return Pair.of(index, value);
}
return Pair.of(index, rexLiteral.getValueAs(BigDecimal.class));
case DATE:
if (value instanceof NlsString) {
value = ((RexLiteral) literal).getValue2();
final Date dateValue = Date.valueOf((String) value);
return Pair.of(index, dateValue);
} else if (value instanceof Calendar) {
final long timeInMillis = ((Calendar) value).getTimeInMillis();
return Pair.of(index, new Date(timeInMillis));
}
case TIME:
return Pair.of(index, rexLiteral.getValueAs(Integer.class));
case TIMESTAMP:
return Pair.of(index, rexLiteral.getValueAs(Long.class));
case CHAR:
if (value instanceof NlsString) {
// TODO: Support collation. Not supported in NlsString compare too.
final NlsString nl = (NlsString) value;
return Pair.of(index, nl.getValue().charAt(0));
}
return Pair.of(index, rexLiteral.getValueAs(Character.class));
case VARCHAR:
if (value instanceof NlsString) {
// TODO: Support coallation. Not supported in {@link #NlsString} compare too.
return Pair.of(index, ((NlsString) value).getValue());
}
return Pair.of(index, rexLiteral.getValueAs(String.class));
default:
//TODO: Support few more supported cases
LOGGER.warn("{} for value of class {} is being handled in default way",
type.getSqlTypeName(), value.getClass());
if (value instanceof NlsString) {
return Pair.of(index, ((NlsString) value).getValue());
type.getSqlTypeName(), rexLiteral.getValue().getClass());
if (rexLiteral.getValue() instanceof NlsString) {
return Pair.of(index, ((NlsString) rexLiteral.getValue()).getValue());
} else {
return Pair.of(index, value);
return Pair.of(index, rexLiteral.getValue());
}
}
}
Expand Down
7 changes: 7 additions & 0 deletions core/src/main/java/org/apache/calcite/rex/RexLiteral.java
Original file line number Diff line number Diff line change
Expand Up @@ -716,6 +716,13 @@ public <T> T getValueAs(Class<T> clazz) {
}
break;
case CHAR:
if (clazz == String.class) {
return clazz.cast(((NlsString) value).getValue());
} else if (clazz == Character.class) {
return clazz.cast(((NlsString) value).getValue().charAt(0));
}
break;
case VARCHAR:
if (clazz == String.class) {
return clazz.cast(((NlsString) value).getValue());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,17 +43,16 @@
import org.apache.calcite.util.TimestampString;
import org.apache.calcite.util.Util;

import org.junit.Ignore;
import org.junit.Test;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import java.math.BigDecimal;
import java.sql.Date;
import java.sql.Time;
import java.sql.Timestamp;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

/**
* Unit tests for {@link RexImplicationChecker}.
*/
Expand Down Expand Up @@ -178,36 +177,46 @@ public class RexImplicationCheckerTest {
f.checkImplies(node1, node1);
}

@Ignore("work in progress")
@Test public void testSimpleDate() {
final Fixture f = new Fixture();
final DateString d = DateString.fromCalendarFields(Util.calendar());
final RexNode node1 = f.ge(f.dt, f.rexBuilder.makeDateLiteral(d));
final RexNode node2 = f.eq(f.dt, f.rexBuilder.makeDateLiteral(d));

f.checkImplies(node2, node1);
f.checkNotImplies(node1, node2);

final DateString dBeforeEpoch1 = DateString.fromDaysSinceEpoch(-12345);
final DateString dBeforeEpcoh2 = DateString.fromDaysSinceEpoch(-123);
final RexNode nodeBe1 = f.lt(f.dt, f.rexBuilder.makeDateLiteral(dBeforeEpoch1));
final RexNode nodeBe2 = f.lt(f.dt, f.rexBuilder.makeDateLiteral(dBeforeEpcoh2));
f.checkImplies(nodeBe1, nodeBe2);
f.checkNotImplies(nodeBe2, nodeBe1);
}

@Ignore("work in progress")
@Test public void testSimpleTimeStamp() {
final Fixture f = new Fixture();
final TimestampString ts =
TimestampString.fromCalendarFields(Util.calendar());
final RexNode node1 = f.le(f.ts, f.timestampLiteral(ts));
final RexNode node1 = f.lt(f.ts, f.timestampLiteral(ts));
final RexNode node2 = f.le(f.ts, f.timestampLiteral(ts));

f.checkImplies(node1, node2);
f.checkNotImplies(node2, node1);

final TimestampString tsBeforeEpoch1 =
TimestampString.fromMillisSinceEpoch(-1234567890L);
final TimestampString tsBeforeEpoch2 =
TimestampString.fromMillisSinceEpoch(-1234567L);
final RexNode nodeBe1 = f.lt(f.ts, f.timestampLiteral(tsBeforeEpoch1));
final RexNode nodeBe2 = f.lt(f.ts, f.timestampLiteral(tsBeforeEpoch2));
f.checkImplies(nodeBe1, nodeBe2);
f.checkNotImplies(nodeBe2, nodeBe1);
}

@Ignore("work in progress")
@Test public void testSimpleTime() {
final Fixture f = new Fixture();
final TimeString t = TimeString.fromCalendarFields(Util.calendar());
final RexNode node1 = f.le(f.ts, f.timeLiteral(t));
final RexNode node2 = f.le(f.ts, f.timeLiteral(t));

final RexNode node1 = f.lt(f.t, f.timeLiteral(t));
final RexNode node2 = f.le(f.t, f.timeLiteral(t));
f.checkImplies(node1, node2);
f.checkNotImplies(node2, node1);
}
Expand Down

0 comments on commit 419b810

Please sign in to comment.