You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@phoenix.apache.org by ja...@apache.org on 2016/02/17 20:56:51 UTC
[3/3] phoenix git commit: PHOENIX-2631 Exception when parsing
boundary timestamp values
PHOENIX-2631 Exception when parsing boundary timestamp values
Project: http://git-wip-us.apache.org/repos/asf/phoenix/repo
Commit: http://git-wip-us.apache.org/repos/asf/phoenix/commit/f1b79d1d
Tree: http://git-wip-us.apache.org/repos/asf/phoenix/tree/f1b79d1d
Diff: http://git-wip-us.apache.org/repos/asf/phoenix/diff/f1b79d1d
Branch: refs/heads/4.x-HBase-1.0
Commit: f1b79d1d18bdfdfa08ba9522a612bee3760460a2
Parents: be4915c
Author: James Taylor <jt...@salesforce.com>
Authored: Tue Feb 16 13:01:45 2016 -0800
Committer: James Taylor <jt...@salesforce.com>
Committed: Wed Feb 17 11:55:44 2016 -0800
----------------------------------------------------------------------
.../end2end/ClientTimeArithmeticQueryIT.java | 11 +-
.../org/apache/phoenix/end2end/DateTimeIT.java | 5 +-
.../apache/phoenix/end2end/DistinctCountIT.java | 2 +-
.../apache/phoenix/end2end/PercentileIT.java | 2 +-
.../phoenix/end2end/ProductMetricsIT.java | 6 +-
.../phoenix/end2end/RowValueConstructorIT.java | 4 +-
.../phoenix/end2end/VariableLengthPKIT.java | 2 +-
.../end2end/index/IndexExpressionIT.java | 7 +-
.../apache/phoenix/end2end/index/IndexIT.java | 5 +-
.../apache/phoenix/schema/types/PDataType.java | 3 +
.../apache/phoenix/schema/types/PTimestamp.java | 407 +++++++++++--------
.../phoenix/compile/WhereOptimizerTest.java | 5 +-
.../java/org/apache/phoenix/query/BaseTest.java | 7 +-
.../org/apache/phoenix/query/QueryPlanTest.java | 24 +-
.../phoenix/schema/types/PDataTypeTest.java | 60 +++
.../java/org/apache/phoenix/util/TestUtil.java | 7 +-
16 files changed, 344 insertions(+), 213 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/phoenix/blob/f1b79d1d/phoenix-core/src/it/java/org/apache/phoenix/end2end/ClientTimeArithmeticQueryIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/ClientTimeArithmeticQueryIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/ClientTimeArithmeticQueryIT.java
index e617673..8347370 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/ClientTimeArithmeticQueryIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/ClientTimeArithmeticQueryIT.java
@@ -19,9 +19,9 @@
*/
package org.apache.phoenix.end2end;
+import static org.apache.phoenix.query.QueryConstants.MILLIS_IN_DAY;
import static org.apache.phoenix.util.TestUtil.B_VALUE;
import static org.apache.phoenix.util.TestUtil.E_VALUE;
-import static org.apache.phoenix.util.TestUtil.MILLIS_IN_DAY;
import static org.apache.phoenix.util.TestUtil.ROW1;
import static org.apache.phoenix.util.TestUtil.ROW2;
import static org.apache.phoenix.util.TestUtil.ROW3;
@@ -51,7 +51,6 @@ import java.util.Properties;
import org.apache.phoenix.util.PhoenixRuntime;
import org.apache.phoenix.util.PropertiesUtil;
-import org.apache.phoenix.util.TestUtil;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@@ -614,10 +613,10 @@ public class ClientTimeArithmeticQueryIT extends BaseQueryIT {
statement.setDate(3, date);
statement.execute();
statement.setString(2, ROW4);
- statement.setDate(3, new Date(date.getTime() + TestUtil.MILLIS_IN_DAY - 1));
+ statement.setDate(3, new Date(date.getTime() + MILLIS_IN_DAY - 1));
statement.execute();
statement.setString(2, ROW6);
- statement.setDate(3, new Date(date.getTime() + TestUtil.MILLIS_IN_DAY - 1));
+ statement.setDate(3, new Date(date.getTime() + MILLIS_IN_DAY - 1));
statement.execute();
statement.setString(2, ROW9);
statement.setDate(3, date);
@@ -738,7 +737,7 @@ public class ClientTimeArithmeticQueryIT extends BaseQueryIT {
conn = DriverManager.getConnection(getUrl(), props);
rs = conn.createStatement().executeQuery("SELECT ts + 1 FROM time_table");
assertTrue(rs.next());
- assertEquals(time.getTime() + TestUtil.MILLIS_IN_DAY,rs.getTimestamp(1).getTime());
+ assertEquals(time.getTime() + MILLIS_IN_DAY,rs.getTimestamp(1).getTime());
}
@Test
@@ -772,7 +771,7 @@ public class ClientTimeArithmeticQueryIT extends BaseQueryIT {
conn = DriverManager.getConnection(getUrl(), props);
rs = conn.createStatement().executeQuery("SELECT ts - 1 FROM time_table");
assertTrue(rs.next());
- assertEquals(time.getTime() - TestUtil.MILLIS_IN_DAY,rs.getTimestamp(1).getTime());
+ assertEquals(time.getTime() - MILLIS_IN_DAY,rs.getTimestamp(1).getTime());
}
@Test
http://git-wip-us.apache.org/repos/asf/phoenix/blob/f1b79d1d/phoenix-core/src/it/java/org/apache/phoenix/end2end/DateTimeIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/DateTimeIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/DateTimeIT.java
index 6c53f1d..e87d8d4 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/DateTimeIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/DateTimeIT.java
@@ -17,12 +17,12 @@
*/
package org.apache.phoenix.end2end;
+import static org.apache.phoenix.query.QueryConstants.MILLIS_IN_DAY;
import static org.apache.phoenix.util.TestUtil.ATABLE_NAME;
import static org.apache.phoenix.util.TestUtil.A_VALUE;
import static org.apache.phoenix.util.TestUtil.B_VALUE;
import static org.apache.phoenix.util.TestUtil.C_VALUE;
import static org.apache.phoenix.util.TestUtil.E_VALUE;
-import static org.apache.phoenix.util.TestUtil.MILLIS_IN_DAY;
import static org.apache.phoenix.util.TestUtil.ROW1;
import static org.apache.phoenix.util.TestUtil.ROW2;
import static org.apache.phoenix.util.TestUtil.ROW3;
@@ -52,7 +52,6 @@ import java.util.Calendar;
import java.util.GregorianCalendar;
import org.apache.phoenix.util.DateUtil;
-import org.apache.phoenix.util.TestUtil;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -672,6 +671,6 @@ public class DateTimeIT extends BaseHBaseManagedTimeIT {
ResultSet rs = conn.createStatement().executeQuery("SELECT CURRENT_DATE()");
assertTrue(rs.next());
long actualTime = rs.getDate(1).getTime();
- assertTrue(Math.abs(actualTime - expectedTime) < TestUtil.MILLIS_IN_DAY);
+ assertTrue(Math.abs(actualTime - expectedTime) < MILLIS_IN_DAY);
}
}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/f1b79d1d/phoenix-core/src/it/java/org/apache/phoenix/end2end/DistinctCountIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/DistinctCountIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/DistinctCountIT.java
index b1daacc..523e83c 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/DistinctCountIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/DistinctCountIT.java
@@ -17,11 +17,11 @@
*/
package org.apache.phoenix.end2end;
+import static org.apache.phoenix.query.QueryConstants.MILLIS_IN_DAY;
import static org.apache.phoenix.util.TestUtil.ATABLE_NAME;
import static org.apache.phoenix.util.TestUtil.A_VALUE;
import static org.apache.phoenix.util.TestUtil.B_VALUE;
import static org.apache.phoenix.util.TestUtil.C_VALUE;
-import static org.apache.phoenix.util.TestUtil.MILLIS_IN_DAY;
import static org.apache.phoenix.util.TestUtil.ROW1;
import static org.apache.phoenix.util.TestUtil.ROW2;
import static org.apache.phoenix.util.TestUtil.ROW3;
http://git-wip-us.apache.org/repos/asf/phoenix/blob/f1b79d1d/phoenix-core/src/it/java/org/apache/phoenix/end2end/PercentileIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/PercentileIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/PercentileIT.java
index 8109694..fe8e5c3 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/PercentileIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/PercentileIT.java
@@ -17,13 +17,13 @@
*/
package org.apache.phoenix.end2end;
+import static org.apache.phoenix.query.QueryConstants.MILLIS_IN_DAY;
import static org.apache.phoenix.util.TestUtil.ATABLE_NAME;
import static org.apache.phoenix.util.TestUtil.A_VALUE;
import static org.apache.phoenix.util.TestUtil.B_VALUE;
import static org.apache.phoenix.util.TestUtil.C_VALUE;
import static org.apache.phoenix.util.TestUtil.INDEX_DATA_SCHEMA;
import static org.apache.phoenix.util.TestUtil.INDEX_DATA_TABLE;
-import static org.apache.phoenix.util.TestUtil.MILLIS_IN_DAY;
import static org.apache.phoenix.util.TestUtil.ROW1;
import static org.apache.phoenix.util.TestUtil.ROW2;
import static org.apache.phoenix.util.TestUtil.ROW3;
http://git-wip-us.apache.org/repos/asf/phoenix/blob/f1b79d1d/phoenix-core/src/it/java/org/apache/phoenix/end2end/ProductMetricsIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/ProductMetricsIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/ProductMetricsIT.java
index ddc5fab..a68ba51 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/ProductMetricsIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/ProductMetricsIT.java
@@ -17,6 +17,7 @@
*/
package org.apache.phoenix.end2end;
+import static org.apache.phoenix.query.QueryConstants.MILLIS_IN_DAY;
import static org.apache.phoenix.util.TestUtil.TEST_PROPERTIES;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -47,7 +48,6 @@ import org.apache.phoenix.util.DateUtil;
import org.apache.phoenix.util.PhoenixRuntime;
import org.apache.phoenix.util.PropertiesUtil;
import org.apache.phoenix.util.SchemaUtil;
-import org.apache.phoenix.util.TestUtil;
import org.junit.Test;
import com.google.common.collect.Lists;
@@ -1983,8 +1983,8 @@ public class ProductMetricsIT extends BaseClientManagedTimeIT {
url = getUrl() + ";" + PhoenixRuntime.CURRENT_SCN_ATTRIB + "=" + (ts); // Run query at timestamp 5
props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
conn = DriverManager.getConnection(url, props);
- initDateTableValues(conn, tenantId, new Date(startDate.getTime()+TestUtil.MILLIS_IN_DAY*10), 2.0);
- initDateTableValues(conn, tenantId, new Date(startDate.getTime()+TestUtil.MILLIS_IN_DAY*20), 2.0);
+ initDateTableValues(conn, tenantId, new Date(startDate.getTime()+MILLIS_IN_DAY*10), 2.0);
+ initDateTableValues(conn, tenantId, new Date(startDate.getTime()+MILLIS_IN_DAY*20), 2.0);
conn.commit();
conn.close();
http://git-wip-us.apache.org/repos/asf/phoenix/blob/f1b79d1d/phoenix-core/src/it/java/org/apache/phoenix/end2end/RowValueConstructorIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/RowValueConstructorIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/RowValueConstructorIT.java
index fef105c..ea91f4f 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/RowValueConstructorIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/RowValueConstructorIT.java
@@ -17,6 +17,7 @@
*/
package org.apache.phoenix.end2end;
+import static org.apache.phoenix.query.QueryConstants.MILLIS_IN_DAY;
import static org.apache.phoenix.util.TestUtil.ENTITYHISTID1;
import static org.apache.phoenix.util.TestUtil.ENTITYHISTID3;
import static org.apache.phoenix.util.TestUtil.ENTITYHISTID7;
@@ -54,7 +55,6 @@ import org.apache.phoenix.util.DateUtil;
import org.apache.phoenix.util.PhoenixRuntime;
import org.apache.phoenix.util.PropertiesUtil;
import org.apache.phoenix.util.QueryUtil;
-import org.apache.phoenix.util.TestUtil;
import org.junit.Test;
@@ -847,7 +847,7 @@ public class RowValueConstructorIT extends BaseClientManagedTimeIT {
try {
PreparedStatement statement = conn.prepareStatement(query);
statement.setString(1, tenantId);
- Timestamp timestampWithNanos = DateUtil.getTimestamp(dateUpserted.getTime() + 2 * TestUtil.MILLIS_IN_DAY, 300);
+ Timestamp timestampWithNanos = DateUtil.getTimestamp(dateUpserted.getTime() + 2 * MILLIS_IN_DAY, 300);
timestampWithNanos.setNanos(0);
statement.setTimestamp(2, timestampWithNanos);
statement.setTimestamp(3, timestampWithNanos);
http://git-wip-us.apache.org/repos/asf/phoenix/blob/f1b79d1d/phoenix-core/src/it/java/org/apache/phoenix/end2end/VariableLengthPKIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/VariableLengthPKIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/VariableLengthPKIT.java
index 1e48f8c..c0b557c 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/VariableLengthPKIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/VariableLengthPKIT.java
@@ -17,8 +17,8 @@
*/
package org.apache.phoenix.end2end;
+import static org.apache.phoenix.query.QueryConstants.MILLIS_IN_DAY;
import static org.apache.phoenix.util.TestUtil.BTABLE_NAME;
-import static org.apache.phoenix.util.TestUtil.MILLIS_IN_DAY;
import static org.apache.phoenix.util.TestUtil.PTSDB2_NAME;
import static org.apache.phoenix.util.TestUtil.PTSDB_NAME;
import static org.apache.phoenix.util.TestUtil.TEST_PROPERTIES;
http://git-wip-us.apache.org/repos/asf/phoenix/blob/f1b79d1d/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/IndexExpressionIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/IndexExpressionIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/IndexExpressionIT.java
index 7be8d41..ed06a71 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/IndexExpressionIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/IndexExpressionIT.java
@@ -9,10 +9,10 @@
*/
package org.apache.phoenix.end2end.index;
+import static org.apache.phoenix.query.QueryConstants.MILLIS_IN_DAY;
import static org.apache.phoenix.util.TestUtil.INDEX_DATA_SCHEMA;
import static org.apache.phoenix.util.TestUtil.INDEX_DATA_TABLE;
import static org.apache.phoenix.util.TestUtil.MUTABLE_INDEX_DATA_TABLE;
-import static org.apache.phoenix.util.TestUtil.NUM_MILLIS_IN_DAY;
import static org.apache.phoenix.util.TestUtil.TEST_PROPERTIES;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -38,7 +38,6 @@ import org.apache.phoenix.util.DateUtil;
import org.apache.phoenix.util.IndexUtil;
import org.apache.phoenix.util.PropertiesUtil;
import org.apache.phoenix.util.QueryUtil;
-import org.apache.phoenix.util.TestUtil;
import org.junit.Test;
public class IndexExpressionIT extends BaseHBaseManagedTimeIT {
@@ -76,7 +75,7 @@ public class IndexExpressionIT extends BaseHBaseManagedTimeIT {
stmt.setInt(3, i);
stmt.setLong(4, i);
stmt.setBigDecimal(5, new BigDecimal(i*0.5d));
- Date date = new Date(DateUtil.parseDate("2015-01-01 00:00:00").getTime() + (i - 1) * TestUtil.NUM_MILLIS_IN_DAY);
+ Date date = new Date(DateUtil.parseDate("2015-01-01 00:00:00").getTime() + (i - 1) * MILLIS_IN_DAY);
stmt.setDate(6, date);
stmt.setString(7, "a.varchar" + String.valueOf(i));
stmt.setString(8, "a.char" + String.valueOf(i));
@@ -99,7 +98,7 @@ public class IndexExpressionIT extends BaseHBaseManagedTimeIT {
+ "_A.VARCHAR" + String.valueOf(i) + "_" + StringUtils.rightPad("B.CHAR" + String.valueOf(i), 10, ' '),
rs.getString(1));
assertEquals(i * 3, rs.getInt(2));
- Date date = new Date(DateUtil.parseDate("2015-01-01 00:00:00").getTime() + (i) * TestUtil.NUM_MILLIS_IN_DAY);
+ Date date = new Date(DateUtil.parseDate("2015-01-01 00:00:00").getTime() + (i) * MILLIS_IN_DAY);
assertEquals(date, rs.getDate(3));
assertEquals(date, rs.getDate(4));
assertEquals(date, rs.getDate(5));
http://git-wip-us.apache.org/repos/asf/phoenix/blob/f1b79d1d/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/IndexIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/IndexIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/IndexIT.java
index 6d54076..4a7e053 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/IndexIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/IndexIT.java
@@ -18,6 +18,7 @@
package org.apache.phoenix.end2end.index;
+import static org.apache.phoenix.query.QueryConstants.MILLIS_IN_DAY;
import static org.apache.phoenix.util.TestUtil.TEST_PROPERTIES;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -519,9 +520,9 @@ public class IndexIT extends BaseHBaseManagedTimeIT {
assertTrue(rs.next());
assertEquals(date, rs.getDate(1));
assertTrue(rs.next());
- assertEquals(new Date(date.getTime() + TestUtil.MILLIS_IN_DAY), rs.getDate(1));
+ assertEquals(new Date(date.getTime() + MILLIS_IN_DAY), rs.getDate(1));
assertTrue(rs.next());
- assertEquals(new Date(date.getTime() + 2 * TestUtil.MILLIS_IN_DAY), rs.getDate(1));
+ assertEquals(new Date(date.getTime() + 2 * MILLIS_IN_DAY), rs.getDate(1));
assertFalse(rs.next());
}
}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/f1b79d1d/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PDataType.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PDataType.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PDataType.java
index 7bf54ce..1b5b695 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PDataType.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PDataType.java
@@ -1116,6 +1116,9 @@ public abstract class PDataType<T> implements DataType<T>, Comparable<PDataType<
*/
if (lowerRange != KeyRange.UNBOUND && !lowerInclusive && isFixedWidth()) {
lowerRange = ByteUtil.nextKey(lowerRange);
+ if (lowerRange == null) { // overflow
+ lowerRange = KeyRange.UNBOUND;
+ }
lowerInclusive = true;
}
return KeyRange.getKeyRange(lowerRange, lowerInclusive, upperRange, upperInclusive);
http://git-wip-us.apache.org/repos/asf/phoenix/blob/f1b79d1d/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PTimestamp.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PTimestamp.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PTimestamp.java
index 16b110e..1f654fe 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PTimestamp.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PTimestamp.java
@@ -24,190 +24,243 @@ import java.text.Format;
import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
import org.apache.hadoop.hbase.util.Bytes;
+import org.apache.phoenix.query.KeyRange;
import org.apache.phoenix.query.QueryConstants;
+import org.apache.phoenix.schema.IllegalDataException;
import org.apache.phoenix.schema.SortOrder;
import org.apache.phoenix.util.ByteUtil;
import org.apache.phoenix.util.DateUtil;
public class PTimestamp extends PDataType<Timestamp> {
+ public static final int MAX_NANOS_VALUE_EXCLUSIVE = 1000000;
+ public static final PTimestamp INSTANCE = new PTimestamp();
- public static final PTimestamp INSTANCE = new PTimestamp();
-
- private PTimestamp() {
- super("TIMESTAMP", Types.TIMESTAMP, java.sql.Timestamp.class,
- new PDate.DateCodec(), 9);
- }
-
- @Override
- public byte[] toBytes(Object object) {
- byte[] bytes = new byte[getByteSize()];
- toBytes(object, bytes, 0);
- return bytes;
- }
-
- @Override
- public int toBytes(Object object, byte[] bytes, int offset) {
- if (object == null) {
- // Create the byte[] of size MAX_TIMESTAMP_BYTES
- if(bytes.length != getByteSize()) {
- bytes = Bytes.padTail(bytes, (getByteSize() - bytes.length));
- }
- PDate.INSTANCE.getCodec().encodeLong(0l, bytes, offset);
- Bytes.putInt(bytes, offset + Bytes.SIZEOF_LONG, 0);
- return getByteSize();
- }
- java.sql.Timestamp value = (java.sql.Timestamp) object;
- PDate.INSTANCE.getCodec().encodeLong(value.getTime(), bytes, offset);
-
- /*
- * By not getting the stuff that got spilled over from the millis part,
- * it leaves the timestamp's byte representation saner - 8 bytes of millis | 4 bytes of nanos.
- * Also, it enables timestamp bytes to be directly compared with date/time bytes.
- */
- Bytes.putInt(bytes, offset + Bytes.SIZEOF_LONG, value.getNanos() % 1000000);
- return getByteSize();
- }
-
- @Override
- public Object toObject(Object object, PDataType actualType) {
- if (object == null) {
- return null;
- }
- if (equalsAny(actualType, PDate.INSTANCE, PUnsignedDate.INSTANCE, PTime.INSTANCE,
- PUnsignedTime.INSTANCE)) {
- return new java.sql.Timestamp(((java.util.Date) object).getTime());
- } else if (equalsAny(actualType, PTimestamp.INSTANCE, PUnsignedTimestamp.INSTANCE)) {
- return object;
- } else if (equalsAny(actualType, PLong.INSTANCE, PUnsignedLong.INSTANCE)) {
- return new java.sql.Timestamp((Long) object);
- } else if (actualType == PDecimal.INSTANCE) {
- BigDecimal bd = (BigDecimal) object;
- long ms = bd.longValue();
- int nanos =
- (bd.remainder(BigDecimal.ONE).multiply(QueryConstants.BD_MILLIS_NANOS_CONVERSION))
- .intValue();
- return DateUtil.getTimestamp(ms, nanos);
- } else if (actualType == PVarchar.INSTANCE) {
- return DateUtil.parseTimestamp((String) object);
- }
- return throwConstraintViolationException(actualType, this);
- }
-
- @Override
- public java.sql.Timestamp toObject(byte[] b, int o, int l, PDataType actualType,
- SortOrder sortOrder, Integer maxLength, Integer scale) {
- if (actualType == null || l == 0) {
- return null;
- }
- java.sql.Timestamp v;
- if (equalsAny(actualType, PTimestamp.INSTANCE, PUnsignedTimestamp.INSTANCE)) {
- long millisDeserialized =
- (actualType == PTimestamp.INSTANCE ? PDate.INSTANCE : PUnsignedDate.INSTANCE).getCodec()
- .decodeLong(b, o, sortOrder);
- v = new java.sql.Timestamp(millisDeserialized);
- int nanosDeserialized =
- PUnsignedInt.INSTANCE.getCodec().decodeInt(b, o + Bytes.SIZEOF_LONG, sortOrder);
- /*
- * There was a bug in serialization of timestamps which was causing the sub-second millis part
- * of time stamp to be present both in the LONG and INT bytes. Having the <100000 check
- * makes this serialization fix backward compatible.
- */
- v.setNanos(
- nanosDeserialized < 1000000 ? v.getNanos() + nanosDeserialized : nanosDeserialized);
- return v;
- } else if (equalsAny(actualType, PDate.INSTANCE, PUnsignedDate.INSTANCE, PTime.INSTANCE,
- PUnsignedTime.INSTANCE, PLong.INSTANCE, PUnsignedLong.INSTANCE)) {
- return new java.sql.Timestamp(actualType.getCodec().decodeLong(b, o, sortOrder));
- } else if (actualType == PDecimal.INSTANCE) {
- BigDecimal bd = (BigDecimal) actualType.toObject(b, o, l, actualType, sortOrder);
- long ms = bd.longValue();
- int nanos = (bd.remainder(BigDecimal.ONE).multiply(QueryConstants.BD_MILLIS_NANOS_CONVERSION))
- .intValue();
- v = DateUtil.getTimestamp(ms, nanos);
- return v;
- }
- throwConstraintViolationException(actualType, this);
- return null;
- }
-
- @Override
- public boolean isCastableTo(PDataType targetType) {
- return PDate.INSTANCE.isCastableTo(targetType);
- }
-
- @Override
- public boolean isCoercibleTo(PDataType targetType) {
- return equalsAny(targetType, this, PVarbinary.INSTANCE, PBinary.INSTANCE);
- }
-
- @Override
- public boolean isCoercibleTo(PDataType targetType, Object value) {
- if (value != null) {
- if (targetType.equals(PUnsignedTimestamp.INSTANCE)) {
- return ((java.util.Date) value).getTime() >= 0;
- } else if (equalsAny(targetType, PUnsignedDate.INSTANCE, PUnsignedTime.INSTANCE)) {
- return ((java.util.Date) value).getTime() >= 0
- && ((java.sql.Timestamp) value).getNanos() == 0;
- } else if (equalsAny(targetType, PDate.INSTANCE, PTime.INSTANCE)) {
- return ((java.sql.Timestamp) value).getNanos() == 0;
- }
- }
- return super.isCoercibleTo(targetType, value);
- }
-
- @Override
- public boolean isFixedWidth() {
- return true;
- }
-
- @Override
- public Integer getByteSize() {
- return MAX_TIMESTAMP_BYTES;
- }
-
- @Override
- public int compareTo(Object lhs, Object rhs, PDataType rhsType) {
- if (equalsAny(rhsType, PTimestamp.INSTANCE, PUnsignedTimestamp.INSTANCE)) {
- return ((java.sql.Timestamp) lhs).compareTo((java.sql.Timestamp) rhs);
- }
- int c = ((java.util.Date) rhs).compareTo((java.util.Date) lhs);
- if (c != 0) return c;
- return ((java.sql.Timestamp) lhs).getNanos();
- }
-
- @Override
- public Object toObject(String value) {
- if (value == null || value.length() == 0) {
- return null;
- }
- return DateUtil.parseTimestamp(value);
- }
-
- @Override
- public String toStringLiteral(Object o, Format formatter) {
- if (formatter == null) {
- formatter = DateUtil.DEFAULT_TIMESTAMP_FORMATTER;
+ private PTimestamp() {
+ super("TIMESTAMP", Types.TIMESTAMP, java.sql.Timestamp.class,
+ new PDate.DateCodec(), 9);
+ }
+
+ @Override
+ public byte[] toBytes(Object object) {
+ byte[] bytes = new byte[getByteSize()];
+ toBytes(object, bytes, 0);
+ return bytes;
+ }
+
+ @Override
+ public int toBytes(Object object, byte[] bytes, int offset) {
+ if (object == null) {
+ // Create the byte[] of size MAX_TIMESTAMP_BYTES
+ if(bytes.length != getByteSize()) {
+ bytes = Bytes.padTail(bytes, (getByteSize() - bytes.length));
+ }
+ PDate.INSTANCE.getCodec().encodeLong(0l, bytes, offset);
+ Bytes.putInt(bytes, offset + Bytes.SIZEOF_LONG, 0);
+ return getByteSize();
+ }
+ java.sql.Timestamp value = (java.sql.Timestamp) object;
+ // For Timestamp, the getTime() method includes milliseconds that may
+ // be stored in the nanos part as well.
+ PDate.INSTANCE.getCodec().encodeLong(value.getTime(), bytes, offset);
+
+ /*
+ * By not getting the stuff that got spilled over from the millis part,
+ * it leaves the timestamp's byte representation saner - 8 bytes of millis | 4 bytes of nanos.
+ * Also, it enables timestamp bytes to be directly compared with date/time bytes.
+ */
+ Bytes.putInt(bytes, offset + Bytes.SIZEOF_LONG, value.getNanos() % MAX_NANOS_VALUE_EXCLUSIVE);
+ return getByteSize();
+ }
+
+ @Override
+ public Object toObject(Object object, PDataType actualType) {
+ if (object == null) {
+ return null;
+ }
+ if (equalsAny(actualType, PDate.INSTANCE, PUnsignedDate.INSTANCE, PTime.INSTANCE,
+ PUnsignedTime.INSTANCE)) {
+ return new java.sql.Timestamp(((java.util.Date) object).getTime());
+ } else if (equalsAny(actualType, PTimestamp.INSTANCE, PUnsignedTimestamp.INSTANCE)) {
+ return object;
+ } else if (equalsAny(actualType, PLong.INSTANCE, PUnsignedLong.INSTANCE)) {
+ return new java.sql.Timestamp((Long) object);
+ } else if (actualType == PDecimal.INSTANCE) {
+ BigDecimal bd = (BigDecimal) object;
+ long ms = bd.longValue();
+ int nanos =
+ (bd.remainder(BigDecimal.ONE).multiply(QueryConstants.BD_MILLIS_NANOS_CONVERSION))
+ .intValue();
+ return DateUtil.getTimestamp(ms, nanos);
+ } else if (actualType == PVarchar.INSTANCE) {
+ return DateUtil.parseTimestamp((String) object);
+ }
+ return throwConstraintViolationException(actualType, this);
+ }
+
+ @Override
+ public java.sql.Timestamp toObject(byte[] b, int o, int l, PDataType actualType,
+ SortOrder sortOrder, Integer maxLength, Integer scale) {
+ if (actualType == null || l == 0) {
+ return null;
+ }
+ java.sql.Timestamp v;
+ if (equalsAny(actualType, PTimestamp.INSTANCE, PUnsignedTimestamp.INSTANCE)) {
+ long millisDeserialized =
+ (actualType == PTimestamp.INSTANCE ? PDate.INSTANCE : PUnsignedDate.INSTANCE).getCodec()
+ .decodeLong(b, o, sortOrder);
+ v = new java.sql.Timestamp(millisDeserialized);
+ int nanosDeserialized =
+ PUnsignedInt.INSTANCE.getCodec().decodeInt(b, o + Bytes.SIZEOF_LONG, sortOrder);
+ /*
+ * There was a bug in serialization of timestamps which was causing the sub-second millis part
+ * of time stamp to be present both in the LONG and INT bytes. Having the <100000 check
+ * makes this serialization fix backward compatible.
+ */
+ v.setNanos(
+ nanosDeserialized < MAX_NANOS_VALUE_EXCLUSIVE ? v.getNanos() + nanosDeserialized : nanosDeserialized);
+ return v;
+ } else if (equalsAny(actualType, PDate.INSTANCE, PUnsignedDate.INSTANCE, PTime.INSTANCE,
+ PUnsignedTime.INSTANCE, PLong.INSTANCE, PUnsignedLong.INSTANCE)) {
+ return new java.sql.Timestamp(actualType.getCodec().decodeLong(b, o, sortOrder));
+ } else if (actualType == PDecimal.INSTANCE) {
+ BigDecimal bd = (BigDecimal) actualType.toObject(b, o, l, actualType, sortOrder);
+ long ms = bd.longValue();
+ int nanos = (bd.remainder(BigDecimal.ONE).multiply(QueryConstants.BD_MILLIS_NANOS_CONVERSION))
+ .intValue();
+ v = DateUtil.getTimestamp(ms, nanos);
+ return v;
+ }
+ throwConstraintViolationException(actualType, this);
+ return null;
+ }
+
+ @Override
+ public boolean isCastableTo(PDataType targetType) {
+ return PDate.INSTANCE.isCastableTo(targetType);
+ }
+
+ @Override
+ public boolean isCoercibleTo(PDataType targetType) {
+ return equalsAny(targetType, this, PVarbinary.INSTANCE, PBinary.INSTANCE);
+ }
+
+ @Override
+ public boolean isCoercibleTo(PDataType targetType, Object value) {
+ if (value != null) {
+ if (targetType.equals(PUnsignedTimestamp.INSTANCE)) {
+ return ((java.util.Date) value).getTime() >= 0;
+ } else if (equalsAny(targetType, PUnsignedDate.INSTANCE, PUnsignedTime.INSTANCE)) {
+ return ((java.util.Date) value).getTime() >= 0
+ && ((java.sql.Timestamp) value).getNanos() == 0;
+ } else if (equalsAny(targetType, PDate.INSTANCE, PTime.INSTANCE)) {
+ return ((java.sql.Timestamp) value).getNanos() == 0;
+ }
+ }
+ return super.isCoercibleTo(targetType, value);
+ }
+
+ @Override
+ public boolean isFixedWidth() {
+ return true;
+ }
+
+ @Override
+ public Integer getByteSize() {
+ return MAX_TIMESTAMP_BYTES;
+ }
+
+ @Override
+ public int compareTo(Object lhs, Object rhs, PDataType rhsType) {
+ if (equalsAny(rhsType, PTimestamp.INSTANCE, PUnsignedTimestamp.INSTANCE)) {
+ return ((java.sql.Timestamp) lhs).compareTo((java.sql.Timestamp) rhs);
+ }
+ int c = ((java.util.Date) rhs).compareTo((java.util.Date) lhs);
+ if (c != 0) return c;
+ return ((java.sql.Timestamp) lhs).getNanos();
+ }
+
+ @Override
+ public Object toObject(String value) {
+ if (value == null || value.length() == 0) {
+ return null;
+ }
+ return DateUtil.parseTimestamp(value);
+ }
+
+ @Override
+ public String toStringLiteral(Object o, Format formatter) {
+ if (formatter == null) {
+ formatter = DateUtil.DEFAULT_TIMESTAMP_FORMATTER;
}
return "'" + super.toStringLiteral(o, formatter) + "'";
- }
-
-
- @Override
- public int getNanos(ImmutableBytesWritable ptr, SortOrder sortOrder) {
- int nanos = PUnsignedInt.INSTANCE.getCodec()
- .decodeInt(ptr.get(), ptr.getOffset() + PLong.INSTANCE.getByteSize(), sortOrder);
- return nanos;
- }
-
- @Override
- public long getMillis(ImmutableBytesWritable ptr, SortOrder sortOrder) {
- long millis = PLong.INSTANCE.getCodec().decodeLong(ptr.get(), ptr.getOffset(), sortOrder);
- return millis;
- }
-
- @Override
- public Object getSampleValue(Integer maxLength, Integer arrayLength) {
- return new java.sql.Timestamp(
- (Long) PLong.INSTANCE.getSampleValue(maxLength, arrayLength));
- }
+ }
+
+
+ @Override
+ public int getNanos(ImmutableBytesWritable ptr, SortOrder sortOrder) {
+ int nanos = PUnsignedInt.INSTANCE.getCodec()
+ .decodeInt(ptr.get(), ptr.getOffset() + PLong.INSTANCE.getByteSize(), sortOrder);
+ return nanos;
+ }
+
+ @Override
+ public long getMillis(ImmutableBytesWritable ptr, SortOrder sortOrder) {
+ long millis = PLong.INSTANCE.getCodec().decodeLong(ptr.get(), ptr.getOffset(), sortOrder);
+ return millis;
+ }
+
+ @Override
+ public Object getSampleValue(Integer maxLength, Integer arrayLength) {
+ return new java.sql.Timestamp(
+ (Long) PLong.INSTANCE.getSampleValue(maxLength, arrayLength));
+ }
+
+ /**
+ * With timestamp, because our last 4 bytes store a value from [0 - 1000000), we need
+ * to detect when the boundary is crossed if we increment to the nextKey.
+ */
+ @Override
+ public KeyRange getKeyRange(byte[] lowerRange, boolean lowerInclusive, byte[] upperRange, boolean upperInclusive) {
+ /*
+ * Force lower bound to be inclusive for fixed width keys because it makes comparisons less expensive when you
+ * can count on one bound or the other being inclusive. Comparing two fixed width exclusive bounds against each
+ * other is inherently more expensive, because you need to take into account if the bigger key is equal to the
+ * next key after the smaller key. For example: (A-B] compared against [A-B) An exclusive lower bound A is
+ * bigger than an exclusive upper bound B. Forcing a fixed width exclusive lower bound key to be inclusive
+ * prevents us from having to do this extra logic in the compare function.
+ *
+ */
+ if (lowerRange != KeyRange.UNBOUND && !lowerInclusive && isFixedWidth()) {
+ if (lowerRange.length != MAX_TIMESTAMP_BYTES) {
+ throw new IllegalDataException("Unexpected size of " + lowerRange.length + " for " + this);
+ }
+ // Infer sortOrder based on most significant byte
+ SortOrder sortOrder = lowerRange[Bytes.SIZEOF_LONG] < 0 ? SortOrder.DESC : SortOrder.ASC;
+ int nanos = PUnsignedInt.INSTANCE.getCodec().decodeInt(lowerRange, Bytes.SIZEOF_LONG, sortOrder);
+ if ((sortOrder == SortOrder.DESC && nanos == 0) || (sortOrder == SortOrder.ASC && nanos == MAX_NANOS_VALUE_EXCLUSIVE-1)) {
+ // With timestamp, because our last 4 bytes store a value from [0 - 1000000), we need
+ // to detect when the boundary is crossed with our nextKey
+ byte[] newLowerRange = new byte[MAX_TIMESTAMP_BYTES];
+ if (sortOrder == SortOrder.DESC) {
+ // Set nanos part as inverted 999999 as it needs to be the max nano value
+ // The millisecond part is moving to the previous value below
+ System.arraycopy(lowerRange, 0, newLowerRange, 0, Bytes.SIZEOF_LONG);
+ PUnsignedInt.INSTANCE.getCodec().encodeInt(MAX_NANOS_VALUE_EXCLUSIVE-1, newLowerRange, Bytes.SIZEOF_LONG);
+ SortOrder.invert(newLowerRange, Bytes.SIZEOF_LONG, newLowerRange, Bytes.SIZEOF_LONG, Bytes.SIZEOF_INT);
+ } else {
+ // Leave nanos part as zero as the millisecond part is rolling over to the next value
+ System.arraycopy(lowerRange, 0, newLowerRange, 0, Bytes.SIZEOF_LONG);
+ }
+ // Increment millisecond part, but leave nanos alone
+ if (ByteUtil.nextKey(newLowerRange, Bytes.SIZEOF_LONG)) {
+ lowerRange = newLowerRange;
+ } else {
+ lowerRange = KeyRange.UNBOUND;
+ }
+ return KeyRange.getKeyRange(lowerRange, true, upperRange, upperInclusive);
+ }
+ }
+ return super.getKeyRange(lowerRange, lowerInclusive, upperRange, upperInclusive);
+ }
+
}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/f1b79d1d/phoenix-core/src/test/java/org/apache/phoenix/compile/WhereOptimizerTest.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/compile/WhereOptimizerTest.java b/phoenix-core/src/test/java/org/apache/phoenix/compile/WhereOptimizerTest.java
index 1b45dc4..9076ea5 100644
--- a/phoenix-core/src/test/java/org/apache/phoenix/compile/WhereOptimizerTest.java
+++ b/phoenix-core/src/test/java/org/apache/phoenix/compile/WhereOptimizerTest.java
@@ -17,6 +17,7 @@
*/
package org.apache.phoenix.compile;
+import static org.apache.phoenix.query.QueryConstants.MILLIS_IN_DAY;
import static org.apache.phoenix.util.TestUtil.BINARY_NAME;
import static org.apache.phoenix.util.TestUtil.TEST_PROPERTIES;
import static org.apache.phoenix.util.TestUtil.assertDegenerate;
@@ -36,8 +37,6 @@ import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.Date;
import java.sql.DriverManager;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.Collections;
@@ -1263,7 +1262,7 @@ public class WhereOptimizerTest extends BaseConnectionlessQueryTest {
String query = "select /*+ RANGE_SCAN */ ORGANIZATION_ID, PARENT_ID, CREATED_DATE, ENTITY_HISTORY_ID from " + TestUtil.ENTITY_HISTORY_TABLE_NAME +
" where ORGANIZATION_ID=? and SUBSTR(PARENT_ID, 1, 3) = ? and CREATED_DATE >= ? and CREATED_DATE < ? order by ORGANIZATION_ID, PARENT_ID, CREATED_DATE, ENTITY_HISTORY_ID limit 6";
Date startTime = new Date(System.currentTimeMillis());
- Date stopTime = new Date(startTime.getTime() + TestUtil.MILLIS_IN_DAY);
+ Date stopTime = new Date(startTime.getTime() + MILLIS_IN_DAY);
List<Object> binds = Arrays.<Object>asList(tenantId, keyPrefix, startTime, stopTime);
StatementContext context = compileStatement(query, binds, 6);
Scan scan = context.getScan();
http://git-wip-us.apache.org/repos/asf/phoenix/blob/f1b79d1d/phoenix-core/src/test/java/org/apache/phoenix/query/BaseTest.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/query/BaseTest.java b/phoenix-core/src/test/java/org/apache/phoenix/query/BaseTest.java
index 9539e69..1192059 100644
--- a/phoenix-core/src/test/java/org/apache/phoenix/query/BaseTest.java
+++ b/phoenix-core/src/test/java/org/apache/phoenix/query/BaseTest.java
@@ -17,6 +17,7 @@
*/
package org.apache.phoenix.query;
+import static org.apache.phoenix.query.QueryConstants.MILLIS_IN_DAY;
import static org.apache.phoenix.util.PhoenixRuntime.CURRENT_SCN_ATTRIB;
import static org.apache.phoenix.util.PhoenixRuntime.JDBC_PROTOCOL;
import static org.apache.phoenix.util.PhoenixRuntime.JDBC_PROTOCOL_TERMINATOR;
@@ -53,7 +54,6 @@ import static org.apache.phoenix.util.TestUtil.JOIN_ORDER_TABLE_FULL_NAME;
import static org.apache.phoenix.util.TestUtil.JOIN_SUPPLIER_TABLE_FULL_NAME;
import static org.apache.phoenix.util.TestUtil.KEYONLY_NAME;
import static org.apache.phoenix.util.TestUtil.MDTEST_NAME;
-import static org.apache.phoenix.util.TestUtil.MILLIS_IN_DAY;
import static org.apache.phoenix.util.TestUtil.MULTI_CF_NAME;
import static org.apache.phoenix.util.TestUtil.MUTABLE_INDEX_DATA_TABLE;
import static org.apache.phoenix.util.TestUtil.PARENTID1;
@@ -159,7 +159,6 @@ import org.apache.phoenix.util.PropertiesUtil;
import org.apache.phoenix.util.QueryUtil;
import org.apache.phoenix.util.ReadOnlyProps;
import org.apache.phoenix.util.SchemaUtil;
-import org.apache.phoenix.util.TestUtil;
import org.apache.twill.discovery.DiscoveryService;
import org.apache.twill.discovery.ZKDiscoveryService;
import org.apache.twill.internal.utils.Networks;
@@ -1933,7 +1932,7 @@ public abstract class BaseTest {
stmt.setInt(13, 3);
stmt.setLong(14, 3L);
stmt.setBigDecimal(15, new BigDecimal("3.1"));
- stmt.setDate(16, date == null ? null : new Date(date.getTime() + TestUtil.MILLIS_IN_DAY));
+ stmt.setDate(16, date == null ? null : new Date(date.getTime() + MILLIS_IN_DAY));
stmt.executeUpdate();
stmt.setString(1, "varchar2");
@@ -1969,7 +1968,7 @@ public abstract class BaseTest {
stmt.setInt(13, 5);
stmt.setLong(14, 5L);
stmt.setBigDecimal(15, new BigDecimal("5.3"));
- stmt.setDate(16, date == null ? null : new Date(date.getTime() + 2 * TestUtil.MILLIS_IN_DAY));
+ stmt.setDate(16, date == null ? null : new Date(date.getTime() + 2 * MILLIS_IN_DAY));
stmt.executeUpdate();
conn.commit();
http://git-wip-us.apache.org/repos/asf/phoenix/blob/f1b79d1d/phoenix-core/src/test/java/org/apache/phoenix/query/QueryPlanTest.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/query/QueryPlanTest.java b/phoenix-core/src/test/java/org/apache/phoenix/query/QueryPlanTest.java
index fdae749..4ba4d16 100644
--- a/phoenix-core/src/test/java/org/apache/phoenix/query/QueryPlanTest.java
+++ b/phoenix-core/src/test/java/org/apache/phoenix/query/QueryPlanTest.java
@@ -26,6 +26,7 @@ import java.sql.Statement;
import java.util.Properties;
import org.apache.phoenix.util.PhoenixRuntime;
+import org.apache.phoenix.util.PropertiesUtil;
import org.apache.phoenix.util.QueryUtil;
import org.junit.Test;
@@ -229,8 +230,27 @@ public class QueryPlanTest extends BaseConnectionlessQueryTest {
}
@Test
- public void testLimitOnTenantSpecific() throws Exception {
-
+ public void testDescTimestampAtBoundary() throws Exception {
+ Properties props = PropertiesUtil.deepCopy(new Properties());
+ Connection conn = DriverManager.getConnection(getUrl(), props);
+ try {
+ conn.createStatement().execute("CREATE TABLE FOO(\n" +
+ " a VARCHAR NOT NULL,\n" +
+ " b TIMESTAMP NOT NULL,\n" +
+ " c VARCHAR,\n" +
+ " CONSTRAINT pk PRIMARY KEY (a, b DESC, c)\n" +
+ " ) IMMUTABLE_ROWS=true\n" +
+ " ,SALT_BUCKETS=20");
+ String query = "select * from foo where a = 'a' and b >= timestamp '2016-01-28 00:00:00' and b < timestamp '2016-01-29 00:00:00'";
+ ResultSet rs = conn.createStatement().executeQuery("EXPLAIN " + query);
+ String queryPlan = QueryUtil.getExplainPlan(rs);
+ assertEquals(
+ "CLIENT PARALLEL 20-WAY RANGE SCAN OVER FOO [0,'a',~'2016-01-28 23:59:59.999'] - [0,'a',~'2016-01-28 00:00:00.000']\n" +
+ " SERVER FILTER BY FIRST KEY ONLY\n" +
+ "CLIENT MERGE SORT", queryPlan);
+ } finally {
+ conn.close();
+ }
}
}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/f1b79d1d/phoenix-core/src/test/java/org/apache/phoenix/schema/types/PDataTypeTest.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/schema/types/PDataTypeTest.java b/phoenix-core/src/test/java/org/apache/phoenix/schema/types/PDataTypeTest.java
index 7a04aeb..085af44 100644
--- a/phoenix-core/src/test/java/org/apache/phoenix/schema/types/PDataTypeTest.java
+++ b/phoenix-core/src/test/java/org/apache/phoenix/schema/types/PDataTypeTest.java
@@ -17,6 +17,7 @@
*/
package org.apache.phoenix.schema.types;
+import static org.apache.phoenix.query.QueryConstants.MILLIS_IN_DAY;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
@@ -38,9 +39,11 @@ import java.util.List;
import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.phoenix.exception.SQLExceptionCode;
+import org.apache.phoenix.query.KeyRange;
import org.apache.phoenix.query.QueryConstants;
import org.apache.phoenix.schema.ConstraintViolationException;
import org.apache.phoenix.schema.SortOrder;
+import org.apache.phoenix.util.DateUtil;
import org.apache.phoenix.util.ScanUtil;
import org.apache.phoenix.util.TestUtil;
import org.junit.Test;
@@ -1832,4 +1835,61 @@ public class PDataTypeTest {
b = PBoolean.INSTANCE.toObject(bytes, 0, bytes.length, PDecimal.INSTANCE, SortOrder.DESC);
assertEquals(false, b);
}
+
+ @Test
+ public void testTimestamp() {
+ long now = System.currentTimeMillis();
+ Timestamp ts1 = DateUtil.getTimestamp(now, 1111);
+ final byte[] bytes1 = PTimestamp.INSTANCE.toBytes(ts1);
+ Timestamp ts2 = DateUtil.getTimestamp(now, 1112);
+ final byte[] bytes2 = PTimestamp.INSTANCE.toBytes(ts2);
+ assertTrue(Bytes.compareTo(bytes1, bytes2) < 0);
+
+ final byte[] ibytes1 = SortOrder.invert(bytes1, 0, bytes1.length);
+ final byte[] ibytes2 = SortOrder.invert(bytes2, 0, bytes2.length);
+ assertTrue(Bytes.compareTo(ibytes1, ibytes2) > 0);
+
+ Timestamp ts3 = new Timestamp(now+1);
+ final byte[] bytes3 = PTimestamp.INSTANCE.toBytes(ts3);
+ assertTrue(Bytes.compareTo(bytes3, bytes2) > 0);
+ final byte[] ibytes3 = SortOrder.invert(bytes3, 0, bytes3.length);
+ assertTrue(Bytes.compareTo(ibytes3, ibytes2) < 0);
+
+ Timestamp ts4 = new Timestamp(now-1);
+ byte[] bytes4 = PTimestamp.INSTANCE.toBytes(ts4);
+ assertTrue(Bytes.compareTo(bytes4, bytes1) < 0);
+ byte[] ibytes4 = SortOrder.invert(bytes4, 0, bytes4.length);
+ assertTrue(Bytes.compareTo(ibytes4, ibytes1) > 0);
+ }
+
+ @Test
+ public void testAscExclusiveTimestampRange() {
+ long now = System.currentTimeMillis();
+ Timestamp ts1 = DateUtil.getTimestamp(now, 999999);
+ final byte[] lowerRange = PTimestamp.INSTANCE.toBytes(ts1);
+ Timestamp ts2 = new Timestamp(now + MILLIS_IN_DAY);
+ final byte[] upperRange = PTimestamp.INSTANCE.toBytes(ts2);
+ KeyRange range = PTimestamp.INSTANCE.getKeyRange(lowerRange, false, upperRange, false);
+ Timestamp ts3 = new Timestamp(now + 1);
+ // Rolled up to next millis
+ final byte[] expectedLowerRange = PTimestamp.INSTANCE.toBytes(ts3);
+ assertTrue(Bytes.compareTo(expectedLowerRange, range.getLowerRange()) == 0);
+ assertTrue(Bytes.compareTo(upperRange, range.getUpperRange()) == 0);
+ }
+
+
+ @Test
+ public void testDescExclusiveTimestampRange() {
+ long now = System.currentTimeMillis();
+ Timestamp ts1 = new Timestamp(now + MILLIS_IN_DAY);
+ final byte[] lowerRange = PTimestamp.INSTANCE.toBytes(ts1, SortOrder.DESC);
+ Timestamp ts2 = new Timestamp(now);
+ final byte[] upperRange = PTimestamp.INSTANCE.toBytes(ts2, SortOrder.DESC);
+ KeyRange range = PTimestamp.INSTANCE.getKeyRange(lowerRange, false, upperRange, false);
+ Timestamp ts3 = DateUtil.getTimestamp(now + MILLIS_IN_DAY - 1, 999999);
+ // Rolled up to next millis
+ final byte[] expectedLowerRange = PTimestamp.INSTANCE.toBytes(ts3, SortOrder.DESC);
+ assertTrue(Bytes.compareTo(expectedLowerRange, range.getLowerRange()) == 0);
+ assertTrue(Bytes.compareTo(upperRange, range.getUpperRange()) == 0);
+ }
}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/f1b79d1d/phoenix-core/src/test/java/org/apache/phoenix/util/TestUtil.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/util/TestUtil.java b/phoenix-core/src/test/java/org/apache/phoenix/util/TestUtil.java
index 66a3c65..c73c160 100644
--- a/phoenix-core/src/test/java/org/apache/phoenix/util/TestUtil.java
+++ b/phoenix-core/src/test/java/org/apache/phoenix/util/TestUtil.java
@@ -17,6 +17,7 @@
*/
package org.apache.phoenix.util;
+import static org.apache.phoenix.query.QueryConstants.MILLIS_IN_DAY;
import static org.apache.phoenix.util.PhoenixRuntime.CONNECTIONLESS;
import static org.apache.phoenix.util.PhoenixRuntime.JDBC_PROTOCOL;
import static org.apache.phoenix.util.PhoenixRuntime.JDBC_PROTOCOL_SEPARATOR;
@@ -155,7 +156,6 @@ public class TestUtil {
public final static List<String> ENTITYHISTIDS = Lists.newArrayList(ENTITYHISTID1, ENTITYHISTID2, ENTITYHISTID3, ENTITYHISTID4, ENTITYHISTID5, ENTITYHISTID6, ENTITYHISTID7, ENTITYHISTID8, ENTITYHISTID9);
- public static final long MILLIS_IN_DAY = 1000 * 60 * 60 * 24;
public static final String LOCALHOST = "localhost";
public static final String PHOENIX_JDBC_URL = JDBC_PROTOCOL + JDBC_PROTOCOL_SEPARATOR + LOCALHOST + JDBC_PROTOCOL_TERMINATOR + PHOENIX_TEST_DRIVER_URL_PARAM;
public static final String PHOENIX_CONNECTIONLESS_JDBC_URL = JDBC_PROTOCOL + JDBC_PROTOCOL_SEPARATOR + CONNECTIONLESS + JDBC_PROTOCOL_TERMINATOR + PHOENIX_TEST_DRIVER_URL_PARAM;
@@ -212,7 +212,6 @@ public class TestUtil {
public static final String JOIN_SUPPLIER_TABLE_DISPLAY_NAME = JOIN_SCHEMA + "." + JOIN_SUPPLIER_TABLE;
public static final String JOIN_COITEM_TABLE_DISPLAY_NAME = JOIN_SCHEMA + "." + JOIN_COITEM_TABLE;
public static final String BINARY_NAME = "BinaryTable";
- public static final int NUM_MILLIS_IN_DAY = 86400000;
/**
* Read-only properties used by all tests
@@ -600,7 +599,7 @@ public class TestUtil {
stmt.setInt(3, i);
stmt.setLong(4, i);
stmt.setBigDecimal(5, new BigDecimal(i*0.5d));
- Date date = new Date(DateUtil.parseDate("2015-01-01 00:00:00").getTime() + (i - 1) * TestUtil.NUM_MILLIS_IN_DAY);
+ Date date = new Date(DateUtil.parseDate("2015-01-01 00:00:00").getTime() + (i - 1) * MILLIS_IN_DAY);
stmt.setDate(6, date);
}
@@ -611,7 +610,7 @@ public class TestUtil {
assertEquals(rs.getInt(3), i);
assertEquals(rs.getInt(4), i);
assertEquals(rs.getBigDecimal(5), new BigDecimal(i*0.5d));
- Date date = new Date(DateUtil.parseDate("2015-01-01 00:00:00").getTime() + (i - 1) * TestUtil.NUM_MILLIS_IN_DAY);
+ Date date = new Date(DateUtil.parseDate("2015-01-01 00:00:00").getTime() + (i - 1) * MILLIS_IN_DAY);
assertEquals(rs.getDate(6), date);
}