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/09/08 19:29:34 UTC
[3/3] phoenix git commit: PHOENIX-2946 Projected comparison between
date and timestamp columns always returns true
PHOENIX-2946 Projected comparison between date and timestamp columns always returns true
Project: http://git-wip-us.apache.org/repos/asf/phoenix/repo
Commit: http://git-wip-us.apache.org/repos/asf/phoenix/commit/aa05da8a
Tree: http://git-wip-us.apache.org/repos/asf/phoenix/tree/aa05da8a
Diff: http://git-wip-us.apache.org/repos/asf/phoenix/diff/aa05da8a
Branch: refs/heads/4.8-HBase-0.98
Commit: aa05da8aed42d9a2e45dc239ec6246c382782267
Parents: fbda580
Author: James Taylor <ja...@apache.org>
Authored: Wed Sep 7 20:18:04 2016 -0700
Committer: James Taylor <ja...@apache.org>
Committed: Thu Sep 8 12:29:02 2016 -0700
----------------------------------------------------------------------
.../expression/function/CeilDateExpression.java | 3 +
.../function/CeilTimestampExpression.java | 3 +
.../expression/function/DateScalarFunction.java | 54 ++
.../expression/function/DayOfMonthFunction.java | 4 +-
.../expression/function/HourFunction.java | 4 +-
.../expression/function/MinuteFunction.java | 4 +-
.../expression/function/MonthFunction.java | 4 +-
.../function/RoundDateExpression.java | 3 +
.../function/RoundJodaDateExpression.java | 3 +
.../expression/function/SecondFunction.java | 4 +-
.../expression/function/ToDateFunction.java | 10 +-
.../expression/function/WeekFunction.java | 4 +-
.../expression/function/YearFunction.java | 4 +-
.../phoenix/jdbc/PhoenixPreparedStatement.java | 26 +-
.../org/apache/phoenix/schema/SortOrder.java | 11 +
.../apache/phoenix/schema/types/PDataType.java | 19 +-
.../org/apache/phoenix/schema/types/PDate.java | 283 +++++-----
.../apache/phoenix/schema/types/PDecimal.java | 6 +-
.../org/apache/phoenix/schema/types/PLong.java | 519 ++++++++++---------
.../org/apache/phoenix/schema/types/PTime.java | 2 +-
.../apache/phoenix/schema/types/PTimestamp.java | 42 +-
.../phoenix/schema/types/PUnsignedDate.java | 259 +++++----
.../phoenix/schema/types/PUnsignedLong.java | 317 +++++------
.../phoenix/schema/types/PUnsignedTime.java | 2 +-
.../schema/types/PUnsignedTimestamp.java | 152 ++----
.../java/org/apache/phoenix/util/DateUtil.java | 22 +
.../phoenix/util/csv/CsvUpsertExecutor.java | 8 +-
.../phoenix/schema/types/PDataTypeTest.java | 18 +
28 files changed, 969 insertions(+), 821 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/phoenix/blob/aa05da8a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/CeilDateExpression.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/CeilDateExpression.java b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/CeilDateExpression.java
index e3cd985..7629409 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/CeilDateExpression.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/CeilDateExpression.java
@@ -93,6 +93,9 @@ public class CeilDateExpression extends RoundDateExpression {
@Override
public boolean evaluate(Tuple tuple, ImmutableBytesWritable ptr) {
if (children.get(0).evaluate(tuple, ptr)) {
+ if (ptr.getLength() == 0) {
+ return true; // child evaluated to null
+ }
PDataType dataType = getDataType();
long time = dataType.getCodec().decodeLong(ptr, children.get(0).getSortOrder());
long value = roundTime(time);
http://git-wip-us.apache.org/repos/asf/phoenix/blob/aa05da8a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/CeilTimestampExpression.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/CeilTimestampExpression.java b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/CeilTimestampExpression.java
index f69f2f8..b3a2a97 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/CeilTimestampExpression.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/CeilTimestampExpression.java
@@ -97,6 +97,9 @@ public class CeilTimestampExpression extends CeilDateExpression {
@Override
public boolean evaluate(Tuple tuple, ImmutableBytesWritable ptr) {
if (children.get(0).evaluate(tuple, ptr)) {
+ if (ptr.getLength() == 0) {
+ return true; // child evaluated to null
+ }
SortOrder sortOrder = children.get(0).getSortOrder();
PDataType dataType = getDataType();
int nanos = dataType.getNanos(ptr, sortOrder);
http://git-wip-us.apache.org/repos/asf/phoenix/blob/aa05da8a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/DateScalarFunction.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/DateScalarFunction.java b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/DateScalarFunction.java
new file mode 100644
index 0000000..aa56a0f
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/DateScalarFunction.java
@@ -0,0 +1,54 @@
+/*
+ * 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.phoenix.expression.function;
+
+import java.io.DataInput;
+import java.io.IOException;
+import java.util.List;
+
+import org.apache.phoenix.expression.Expression;
+import org.apache.phoenix.schema.types.PDataType;
+import org.apache.phoenix.schema.types.PDataType.PDataCodec;
+import org.apache.phoenix.util.DateUtil;
+
+public abstract class DateScalarFunction extends ScalarFunction {
+ protected PDataCodec inputCodec;
+
+ public DateScalarFunction() {
+ }
+
+ public DateScalarFunction(List<Expression> children) {
+ super(children);
+ init();
+ }
+
+ protected final PDataCodec getInputCodec() {
+ return inputCodec;
+ }
+
+ @Override
+ public void readFields(DataInput input) throws IOException {
+ super.readFields(input);
+ init();
+ }
+
+ private void init() {
+ PDataType returnType = getChildren().get(0).getDataType();
+ inputCodec = DateUtil.getCodecFor(returnType);
+ }
+}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/aa05da8a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/DayOfMonthFunction.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/DayOfMonthFunction.java b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/DayOfMonthFunction.java
index 0c328cf..fb5a68a 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/DayOfMonthFunction.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/DayOfMonthFunction.java
@@ -38,7 +38,7 @@ import org.joda.time.DateTime;
*/
@BuiltInFunction(name=DayOfMonthFunction.NAME,
args={@Argument(allowedTypes={PTimestamp.class})})
-public class DayOfMonthFunction extends ScalarFunction {
+public class DayOfMonthFunction extends DateScalarFunction {
public static final String NAME = "DAYOFMONTH";
public DayOfMonthFunction() {
@@ -57,7 +57,7 @@ public class DayOfMonthFunction extends ScalarFunction {
if ( ptr.getLength() == 0) {
return true; //means null
}
- long dateTime = expression.getDataType().getCodec().decodeLong(ptr, expression.getSortOrder());
+ long dateTime = inputCodec.decodeLong(ptr, expression.getSortOrder());
DateTime dt = new DateTime(dateTime);
int day = dt.getDayOfMonth();
PDataType returnType = getDataType();
http://git-wip-us.apache.org/repos/asf/phoenix/blob/aa05da8a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/HourFunction.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/HourFunction.java b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/HourFunction.java
index 0e9efd8..7b9c8c0 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/HourFunction.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/HourFunction.java
@@ -37,7 +37,7 @@ import org.apache.phoenix.schema.types.PTimestamp;
*/
@BuiltInFunction(name=HourFunction.NAME,
args={@Argument(allowedTypes={PTimestamp.class})})
-public class HourFunction extends ScalarFunction {
+public class HourFunction extends DateScalarFunction {
public static final String NAME = "HOUR";
public HourFunction() {
@@ -56,7 +56,7 @@ public class HourFunction extends ScalarFunction {
if ( ptr.getLength() == 0) {
return true; //means null
}
- long dateTime = expression.getDataType().getCodec().decodeLong(ptr, expression.getSortOrder());
+ long dateTime = inputCodec.decodeLong(ptr, expression.getSortOrder());
int hour = (int)(((dateTime/1000) % (24*3600))/3600);
PDataType returnType = getDataType();
byte[] byteValue = new byte[returnType.getByteSize()];
http://git-wip-us.apache.org/repos/asf/phoenix/blob/aa05da8a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/MinuteFunction.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/MinuteFunction.java b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/MinuteFunction.java
index fc721fc..6766e35 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/MinuteFunction.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/MinuteFunction.java
@@ -37,7 +37,7 @@ import org.apache.phoenix.schema.types.PTimestamp;
*/
@BuiltInFunction(name=MinuteFunction.NAME,
args={@Argument(allowedTypes={PTimestamp.class})})
-public class MinuteFunction extends ScalarFunction {
+public class MinuteFunction extends DateScalarFunction {
public static final String NAME = "MINUTE";
public MinuteFunction() {
@@ -56,7 +56,7 @@ public class MinuteFunction extends ScalarFunction {
if ( ptr.getLength() == 0) {
return true; //means null
}
- long dateTime = expression.getDataType().getCodec().decodeLong(ptr, expression.getSortOrder());
+ long dateTime = inputCodec.decodeLong(ptr, expression.getSortOrder());
int minute = (int)(((dateTime/1000) % 3600)/60);
PDataType returnType = getDataType();
byte[] byteValue = new byte[returnType.getByteSize()];
http://git-wip-us.apache.org/repos/asf/phoenix/blob/aa05da8a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/MonthFunction.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/MonthFunction.java b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/MonthFunction.java
index 5ad6c34..bd6ff3e 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/MonthFunction.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/MonthFunction.java
@@ -38,7 +38,7 @@ import org.joda.time.DateTime;
*/
@BuiltInFunction(name=MonthFunction.NAME,
args={@Argument(allowedTypes={PTimestamp.class})})
-public class MonthFunction extends ScalarFunction {
+public class MonthFunction extends DateScalarFunction {
public static final String NAME = "MONTH";
public MonthFunction() {
@@ -57,7 +57,7 @@ public class MonthFunction extends ScalarFunction {
if ( ptr.getLength() == 0) {
return true; //means null
}
- long dateTime = expression.getDataType().getCodec().decodeLong(ptr, expression.getSortOrder());
+ long dateTime = inputCodec.decodeLong(ptr, expression.getSortOrder());
DateTime dt = new DateTime(dateTime);
int month = dt.getMonthOfYear();
PDataType returnType = getDataType();
http://git-wip-us.apache.org/repos/asf/phoenix/blob/aa05da8a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RoundDateExpression.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RoundDateExpression.java b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RoundDateExpression.java
index e2483ac..a80d745 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RoundDateExpression.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RoundDateExpression.java
@@ -151,6 +151,9 @@ public class RoundDateExpression extends ScalarFunction {
@Override
public boolean evaluate(Tuple tuple, ImmutableBytesWritable ptr) {
if (children.get(0).evaluate(tuple, ptr)) {
+ if (ptr.getLength() == 0) {
+ return true; // child evaluated to null
+ }
PDataType dataType = getDataType();
long time = dataType.getCodec().decodeLong(ptr, children.get(0).getSortOrder());
long value = roundTime(time);
http://git-wip-us.apache.org/repos/asf/phoenix/blob/aa05da8a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RoundJodaDateExpression.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RoundJodaDateExpression.java b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RoundJodaDateExpression.java
index 0dba80b..356c85f 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RoundJodaDateExpression.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RoundJodaDateExpression.java
@@ -43,6 +43,9 @@ public abstract class RoundJodaDateExpression extends RoundDateExpression{
@Override
public boolean evaluate(Tuple tuple, ImmutableBytesWritable ptr) {
if (children.get(0).evaluate(tuple, ptr)) {
+ if (ptr.getLength() == 0) {
+ return true; // child evaluated to null
+ }
PDataType dataType = getDataType();
long time = dataType.getCodec().decodeLong(ptr, children.get(0).getSortOrder());
DateTime dt = new DateTime(time,ISOChronology.getInstanceUTC());
http://git-wip-us.apache.org/repos/asf/phoenix/blob/aa05da8a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/SecondFunction.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/SecondFunction.java b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/SecondFunction.java
index 5f39786..02bc455 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/SecondFunction.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/SecondFunction.java
@@ -37,7 +37,7 @@ import org.apache.phoenix.schema.types.PTimestamp;
*/
@BuiltInFunction(name=SecondFunction.NAME,
args={@Argument(allowedTypes={PTimestamp.class})})
-public class SecondFunction extends ScalarFunction {
+public class SecondFunction extends DateScalarFunction {
public static final String NAME = "SECOND";
public SecondFunction() {
@@ -56,7 +56,7 @@ public class SecondFunction extends ScalarFunction {
if ( ptr.getLength() == 0) {
return true; //means null
}
- long dateTime = expression.getDataType().getCodec().decodeLong(ptr, expression.getSortOrder());
+ long dateTime = inputCodec.decodeLong(ptr, expression.getSortOrder());
int sec = (int)((dateTime/1000) % 60);
PDataType returnType = getDataType();
byte[] byteValue = new byte[returnType.getByteSize()];
http://git-wip-us.apache.org/repos/asf/phoenix/blob/aa05da8a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ToDateFunction.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ToDateFunction.java b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ToDateFunction.java
index 17f6847..1930d92 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ToDateFunction.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ToDateFunction.java
@@ -32,6 +32,7 @@ import org.apache.phoenix.parse.FunctionParseNode.BuiltInFunction;
import org.apache.phoenix.parse.ToDateParseNode;
import org.apache.phoenix.schema.tuple.Tuple;
import org.apache.phoenix.schema.types.PDataType;
+import org.apache.phoenix.schema.types.PDataType.PDataCodec;
import org.apache.phoenix.schema.types.PDate;
import org.apache.phoenix.schema.types.PVarchar;
import org.apache.phoenix.util.DateUtil;
@@ -53,6 +54,7 @@ import org.apache.phoenix.util.DateUtil;
public class ToDateFunction extends ScalarFunction {
public static final String NAME = "TO_DATE";
private DateUtil.DateTimeParser dateParser;
+ private PDataCodec codec;
protected String dateFormat;
protected String timeZoneId;
@@ -80,6 +82,7 @@ public class ToDateFunction extends ScalarFunction {
// server to evaluate using the local time zone. Instead, we want
// to use the client local time zone.
this.timeZoneId = this.dateParser.getTimeZone().getID();
+ this.codec = DateUtil.getCodecFor(getDataType());
}
@Override
@@ -110,15 +113,18 @@ public class ToDateFunction extends ScalarFunction {
@Override
public boolean evaluate(Tuple tuple, ImmutableBytesWritable ptr) {
Expression expression = getExpression();
- if (!expression.evaluate(tuple, ptr) || ptr.getLength() == 0) {
+ if (!expression.evaluate(tuple, ptr)) {
return false;
}
+ if (ptr.getLength() == 0) {
+ return true;
+ }
PDataType type = expression.getDataType();
String dateStr = (String)type.toObject(ptr, expression.getSortOrder());
long epochTime = dateParser.parseDateTime(dateStr);
PDataType returnType = getDataType();
byte[] byteValue = new byte[returnType.getByteSize()];
- returnType.getCodec().encodeLong(epochTime, byteValue, 0);
+ codec.encodeLong(epochTime, byteValue, 0);
ptr.set(byteValue);
return true;
}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/aa05da8a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/WeekFunction.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/WeekFunction.java b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/WeekFunction.java
index 126aba8..3f6d772 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/WeekFunction.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/WeekFunction.java
@@ -38,7 +38,7 @@ import org.joda.time.DateTime;
*/
@BuiltInFunction(name=WeekFunction.NAME,
args={@Argument(allowedTypes={PTimestamp.class})})
-public class WeekFunction extends ScalarFunction {
+public class WeekFunction extends DateScalarFunction {
public static final String NAME = "WEEK";
public WeekFunction() {
@@ -57,7 +57,7 @@ public class WeekFunction extends ScalarFunction {
if ( ptr.getLength() == 0) {
return true; //means null
}
- long dateTime = expression.getDataType().getCodec().decodeLong(ptr, expression.getSortOrder());
+ long dateTime = inputCodec.decodeLong(ptr, expression.getSortOrder());
DateTime dt = new DateTime(dateTime);
int week = dt.getWeekOfWeekyear();
PDataType returnType = getDataType();
http://git-wip-us.apache.org/repos/asf/phoenix/blob/aa05da8a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/YearFunction.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/YearFunction.java b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/YearFunction.java
index f1958e1..fcab8d2 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/YearFunction.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/YearFunction.java
@@ -37,7 +37,7 @@ import org.joda.time.DateTime;
*/
@BuiltInFunction(name=YearFunction.NAME,
args={@Argument(allowedTypes={PTimestamp.class})})
-public class YearFunction extends ScalarFunction {
+public class YearFunction extends DateScalarFunction {
public static final String NAME = "YEAR";
public YearFunction() {
@@ -56,7 +56,7 @@ public class YearFunction extends ScalarFunction {
if ( ptr.getLength() == 0) {
return true; //means null
}
- long dateTime = expression.getDataType().getCodec().decodeLong(ptr, expression.getSortOrder());
+ long dateTime = inputCodec.decodeLong(ptr, expression.getSortOrder());
DateTime dt = new DateTime(dateTime);
int year = dt.getYear();
PDataType returnType = getDataType();
http://git-wip-us.apache.org/repos/asf/phoenix/blob/aa05da8a/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixPreparedStatement.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixPreparedStatement.java b/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixPreparedStatement.java
index 9c6a94b..9bba3d3 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixPreparedStatement.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixPreparedStatement.java
@@ -361,11 +361,17 @@ public class PhoenixPreparedStatement extends PhoenixStatement implements Prepar
@Override
public void setDate(int parameterIndex, Date x) throws SQLException {
+ if (x != null) { // Since Date is mutable, make a copy
+ x = new Date(x.getTime());
+ }
setParameter(parameterIndex, x);
}
@Override
public void setDate(int parameterIndex, Date x, Calendar cal) throws SQLException {
+ if (x != null) { // Since Date is mutable, make a copy
+ x = new Date(x.getTime());
+ }
cal.setTime(x);
setParameter(parameterIndex, new Date(cal.getTimeInMillis()));
}
@@ -475,23 +481,39 @@ public class PhoenixPreparedStatement extends PhoenixStatement implements Prepar
@Override
public void setTime(int parameterIndex, Time x) throws SQLException {
+ if (x != null) { // Since Time is mutable, make a copy
+ x = new Time(x.getTime());
+ }
setParameter(parameterIndex, x);
}
@Override
public void setTime(int parameterIndex, Time x, Calendar cal) throws SQLException {
+ if (x != null) { // Since Time is mutable, make a copy
+ x = new Time(x.getTime());
+ }
cal.setTime(x);
setParameter(parameterIndex, new Time(cal.getTimeInMillis()));
}
+ private void setTimestampParameter(int parameterIndex, Timestamp x, Calendar cal) throws SQLException {
+ if (x != null) { // Since Timestamp is mutable, make a copy
+ int nanos = x.getNanos();
+ x = new Timestamp(x.getTime());
+ x.setNanos(nanos);
+ }
+ // TODO: deal with Calendar
+ setParameter(parameterIndex, x);
+ }
+
@Override
public void setTimestamp(int parameterIndex, Timestamp x) throws SQLException {
- setParameter(parameterIndex, x);
+ setTimestampParameter(parameterIndex, x, null);
}
@Override
public void setTimestamp(int parameterIndex, Timestamp x, Calendar cal) throws SQLException {
- setParameter(parameterIndex, x);
+ setTimestampParameter(parameterIndex, x, cal);
}
@Override
http://git-wip-us.apache.org/repos/asf/phoenix/blob/aa05da8a/phoenix-core/src/main/java/org/apache/phoenix/schema/SortOrder.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/SortOrder.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/SortOrder.java
index 91b6cd0..1d32a06 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/SortOrder.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/SortOrder.java
@@ -55,6 +55,11 @@ public enum SortOrder {
public CompareOp transform(CompareOp op) {
return op;
}
+
+ @Override
+ public byte normalize(byte b) {
+ return b;
+ }
},
DESC(1) {
@@ -71,6 +76,11 @@ public enum SortOrder {
}
throw new IllegalArgumentException("Add the missing case statement!");
}
+
+ @Override
+ public byte normalize(byte b) {
+ return SortOrder.invert(b);
+ }
};
/**
@@ -137,4 +147,5 @@ public enum SortOrder {
}
public abstract CompareOp transform(CompareOp op);
+ public abstract byte normalize(byte b);
}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/aa05da8a/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 0f0328a..5d611e9 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
@@ -89,8 +89,7 @@ public abstract class PDataType<T> implements DataType<T>, Comparable<PDataType<
}
public boolean isBytesComparableWith(PDataType otherType) {
- return this == otherType || this.getClass() == PVarbinary.class || otherType == PVarbinary.INSTANCE
- || this.getClass() == PBinary.class || otherType == PBinary.INSTANCE;
+ return equalsAny(this, otherType, PVarbinary.INSTANCE, PBinary.INSTANCE);
}
public int estimateByteSize(Object o) {
@@ -151,6 +150,18 @@ public abstract class PDataType<T> implements DataType<T>, Comparable<PDataType<
// Special case as we may be comparing two arrays that have different separator characters due to PHOENIX-2067
if (!this.isArrayType() || !rhsType.isArrayType() ||
PArrayDataType.isRowKeyOrderOptimized(this, lhsSortOrder, lhs, lhsOffset, lhsLength) == PArrayDataType.isRowKeyOrderOptimized(rhsType, rhsSortOrder, rhs, rhsOffset, rhsLength)) {
+ // Ignore trailing zero bytes if fixed byte length (for example TIMESTAMP compared to DATE)
+ if (lhsLength != rhsLength && this.isFixedWidth() && rhsType.isFixedWidth() && this.getByteSize() != null && rhsType.getByteSize() != null) {
+ if (lhsLength > rhsLength) {
+ int minOffset = lhsOffset + rhsLength;
+ for (int i = lhsOffset + lhsLength - 1; i >= minOffset && lhsSortOrder.normalize(lhs[i]) == 0; i--,lhsLength--) {
+ }
+ } else {
+ int minOffset = rhsOffset + lhsLength;
+ for (int i = rhsOffset + rhsLength - 1; i >= minOffset && rhsSortOrder.normalize(rhs[i]) == 0; i--,rhsLength--) {
+ }
+ }
+ }
return compareTo(lhs, lhsOffset, lhsLength, lhsSortOrder, rhs, rhsOffset, rhsLength, rhsSortOrder);
}
}
@@ -196,8 +207,8 @@ public abstract class PDataType<T> implements DataType<T>, Comparable<PDataType<
return Bytes.compareTo(lhsConverted, 0, lhsConverted.length, rhs, rhsOffset, rhsLength);
}
// convert to native and compare
- if (this.isCoercibleTo(PLong.INSTANCE) && rhsType.isCoercibleTo(PLong.INSTANCE)) { // native long to long
- // comparison
+ if ( (this.isCoercibleTo(PLong.INSTANCE) || this.isCoercibleTo(PDate.INSTANCE)) &&
+ (rhsType.isCoercibleTo(PLong.INSTANCE) || rhsType.isCoercibleTo(PDate.INSTANCE)) ) {
return Longs.compare(this.getCodec().decodeLong(lhs, lhsOffset, lhsSortOrder), rhsType.getCodec()
.decodeLong(rhs, rhsOffset, rhsSortOrder));
} else if (isDoubleOrFloat(this) && isDoubleOrFloat(rhsType)) { // native double to double comparison
http://git-wip-us.apache.org/repos/asf/phoenix/blob/aa05da8a/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PDate.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PDate.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PDate.java
index c27d0fc..d70a658 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PDate.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PDate.java
@@ -30,122 +30,124 @@ import org.apache.phoenix.util.StringUtil;
public class PDate extends PDataType<Date> {
- public static final PDate INSTANCE = new PDate();
-
- private PDate() {
- super("DATE", Types.DATE, Date.class,
- new DateCodec(), 11); // After TIMESTAMP and DATE to ensure toLiteral finds those first
- }
-
- @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) {
- getCodec().encodeLong(0l, bytes, offset);
+ public static final PDate INSTANCE = new PDate();
+
+ private PDate() {
+ super("DATE", Types.DATE, Date.class,
+ new DateCodec(), 11); // After TIMESTAMP and DATE to ensure toLiteral finds those first
+ }
+
+ @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) {
+ getCodec().encodeLong(0l, bytes, offset);
+ return this.getByteSize();
+ }
+ getCodec().encodeLong(((java.util.Date) object).getTime(), bytes, offset);
return this.getByteSize();
}
- getCodec().encodeLong(((java.util.Date) object).getTime(), bytes, offset);
- return this.getByteSize();
- }
-
- @Override
- public Object toObject(Object object, PDataType actualType) {
- if (object == null) {
- return null;
- }
- if (equalsAny(actualType, PTime.INSTANCE, PUnsignedTime.INSTANCE)) {
- return new Date(((java.sql.Time) object).getTime());
- } else if (equalsAny(actualType, PTimestamp.INSTANCE, PUnsignedTimestamp.INSTANCE)) {
- return new Date(((java.sql.Timestamp) object).getTime());
- } else if (equalsAny(actualType, PDate.INSTANCE, PUnsignedDate.INSTANCE)) {
- return object;
- } else if (equalsAny(actualType, PLong.INSTANCE, PUnsignedLong.INSTANCE)) {
- return new Date((Long) object);
- } else if (actualType == PDecimal.INSTANCE) {
- return new Date(((BigDecimal) object).longValueExact());
- } else if (actualType == PVarchar.INSTANCE) {
- return DateUtil.parseDate((String) object);
- }
- return throwConstraintViolationException(actualType, this);
- }
-
- @Override
- public Date toObject(byte[] b, int o, int l, PDataType actualType, SortOrder sortOrder, Integer maxLength, Integer scale) {
- if (l == 0) {
- return null;
- }
- if (equalsAny(actualType, PTimestamp.INSTANCE, PUnsignedTimestamp.INSTANCE, PDate.INSTANCE,
- PUnsignedDate.INSTANCE, PTime.INSTANCE, PUnsignedTime.INSTANCE, PLong.INSTANCE,
- PUnsignedLong.INSTANCE)) {
- return new Date(actualType.getCodec().decodeLong(b, o, sortOrder));
- } else if (actualType == PDecimal.INSTANCE) {
- BigDecimal bd = (BigDecimal) actualType.toObject(b, o, l, actualType, sortOrder);
- return new Date(bd.longValueExact());
- }
- throwConstraintViolationException(actualType, this);
- return null;
- }
-
- @Override
- public boolean isCastableTo(PDataType targetType) {
- return super.isCastableTo(targetType) ||
- equalsAny(targetType, PDecimal.INSTANCE, PLong.INSTANCE, PUnsignedLong.INSTANCE);
- }
-
- @Override
- public boolean isCoercibleTo(PDataType targetType) {
- return equalsAny(targetType, PDate.INSTANCE, PTime.INSTANCE, PTimestamp.INSTANCE, PVarbinary.INSTANCE, PBinary.INSTANCE);
- }
-
- @Override
- public boolean isCoercibleTo(PDataType targetType, Object value) {
- if (value != null) {
- if (equalsAny(targetType, PUnsignedTimestamp.INSTANCE, PUnsignedDate.INSTANCE,
- PUnsignedTime.INSTANCE)) {
- return ((java.util.Date) value).getTime() >= 0;
- }
- }
- return super.isCoercibleTo(targetType, value);
- }
-
- @Override
- public boolean isFixedWidth() {
- return true;
- }
-
- @Override
- public Integer getByteSize() {
- return Bytes.SIZEOF_LONG;
- }
-
- @Override
- public int compareTo(Object lhs, Object rhs, PDataType rhsType) {
- if (rhsType == PTimestamp.INSTANCE || rhsType == PUnsignedTimestamp.INSTANCE) {
- return -rhsType.compareTo(rhs, lhs, PTime.INSTANCE);
- }
- return ((java.util.Date) lhs).compareTo((java.util.Date) rhs);
- }
-
- @Override
- public Object toObject(String value) {
- if (value == null || value.length() == 0) {
- return null;
- }
- return DateUtil.parseDate(value);
- }
-
- @Override
- public boolean isBytesComparableWith(PDataType otherType) {
- return super.isBytesComparableWith(otherType) || otherType == PTime.INSTANCE;
- }
-
- @Override
+
+ @Override
+ public Object toObject(Object object, PDataType actualType) {
+ if (object == null) {
+ return null;
+ }
+ if (equalsAny(actualType, PTime.INSTANCE, PUnsignedTime.INSTANCE)) {
+ return new Date(((java.sql.Time) object).getTime());
+ } else if (equalsAny(actualType, PTimestamp.INSTANCE, PUnsignedTimestamp.INSTANCE)) {
+ return new Date(((java.sql.Timestamp) object).getTime());
+ } else if (equalsAny(actualType, PDate.INSTANCE, PUnsignedDate.INSTANCE)) {
+ return object;
+ } else if (equalsAny(actualType, PLong.INSTANCE, PUnsignedLong.INSTANCE)) {
+ return new Date((Long) object);
+ } else if (actualType == PDecimal.INSTANCE) {
+ return new Date(((BigDecimal) object).longValueExact());
+ } else if (actualType == PVarchar.INSTANCE) {
+ return DateUtil.parseDate((String) object);
+ }
+ return throwConstraintViolationException(actualType, this);
+ }
+
+ @Override
+ public Date toObject(byte[] b, int o, int l, PDataType actualType, SortOrder sortOrder, Integer maxLength, Integer scale) {
+ if (l == 0) {
+ return null;
+ }
+ if (actualType.getCodec() != null ) {
+ return new Date(actualType.getCodec().decodeLong(b, o, sortOrder));
+ } else if (actualType == PTimestamp.INSTANCE) {
+ return new Date(PDate.INSTANCE.getCodec().decodeLong(b, o, sortOrder));
+ } else if (actualType == PUnsignedTimestamp.INSTANCE) {
+ return new Date(PUnsignedDate.INSTANCE.getCodec().decodeLong(b, o, sortOrder));
+ } else if (actualType == PDecimal.INSTANCE) {
+ BigDecimal bd = (BigDecimal) actualType.toObject(b, o, l, actualType, sortOrder);
+ return new Date(bd.longValueExact());
+ }
+ throwConstraintViolationException(actualType, this);
+ return null;
+ }
+
+ @Override
+ public boolean isCastableTo(PDataType targetType) {
+ return super.isCastableTo(targetType) ||
+ equalsAny(targetType, PDecimal.INSTANCE, PLong.INSTANCE, PUnsignedLong.INSTANCE);
+ }
+
+ @Override
+ public boolean isCoercibleTo(PDataType targetType) {
+ return equalsAny(targetType, PDate.INSTANCE, PTime.INSTANCE, PTimestamp.INSTANCE, PVarbinary.INSTANCE, PBinary.INSTANCE);
+ }
+
+ @Override
+ public boolean isCoercibleTo(PDataType targetType, Object value) {
+ if (value != null) {
+ if (equalsAny(targetType, PUnsignedTimestamp.INSTANCE, PUnsignedDate.INSTANCE,
+ PUnsignedTime.INSTANCE)) {
+ return ((java.util.Date) value).getTime() >= 0;
+ }
+ }
+ return super.isCoercibleTo(targetType, value);
+ }
+
+ @Override
+ public boolean isFixedWidth() {
+ return true;
+ }
+
+ @Override
+ public Integer getByteSize() {
+ return Bytes.SIZEOF_LONG;
+ }
+
+ @Override
+ public int compareTo(Object lhs, Object rhs, PDataType rhsType) {
+ if (rhsType == PTimestamp.INSTANCE || rhsType == PUnsignedTimestamp.INSTANCE) {
+ return -rhsType.compareTo(rhs, lhs, PTime.INSTANCE);
+ }
+ return ((java.util.Date) lhs).compareTo((java.util.Date) rhs);
+ }
+
+ @Override
+ public Object toObject(String value) {
+ if (value == null || value.length() == 0) {
+ return null;
+ }
+ return DateUtil.parseDate(value);
+ }
+
+ @Override
+ public boolean isBytesComparableWith(PDataType otherType) {
+ return super.isBytesComparableWith(otherType) || otherType == PTime.INSTANCE || otherType == PTimestamp.INSTANCE || otherType == PLong.INSTANCE;
+ }
+
+ @Override
public String toStringLiteral(Object o, Format formatter) {
if (formatter == null) {
// If default formatter has not been overridden,
@@ -156,40 +158,39 @@ public class PDate extends PDataType<Date> {
+ StringUtil.escapeStringConstant(super.toStringLiteral(o, formatter)) + "'";
}
- @Override
- public void coerceBytes(ImmutableBytesWritable ptr, Object object, PDataType actualType,
- Integer maxLength, Integer scale, SortOrder actualModifier, Integer desiredMaxLength, Integer desiredScale,
- SortOrder expectedModifier) {
- if (ptr.getLength() > 0 && actualType == PTimestamp.INSTANCE
- && actualModifier == expectedModifier) {
- ptr.set(ptr.get(), ptr.getOffset(), getByteSize());
- return;
+ @Override
+ public void coerceBytes(ImmutableBytesWritable ptr, Object object, PDataType actualType,
+ Integer maxLength, Integer scale, SortOrder actualModifier, Integer desiredMaxLength, Integer desiredScale,
+ SortOrder expectedModifier) {
+ // Decrease size of TIMESTAMP to size of DATE and continue coerce
+ if (ptr.getLength() > getByteSize()) {
+ ptr.set(ptr.get(), ptr.getOffset(), getByteSize());
+ }
+ super.coerceBytes(ptr, object, actualType, maxLength, scale, actualModifier, desiredMaxLength,
+ desiredScale, expectedModifier);
}
- super.coerceBytes(ptr, object, actualType, maxLength, scale, actualModifier, desiredMaxLength,
- desiredScale, expectedModifier);
- }
-
- @Override
- public Object getSampleValue(Integer maxLength, Integer arrayLength) {
- return new Date((Long) PLong.INSTANCE.getSampleValue(maxLength, arrayLength));
- }
-
- static class DateCodec extends PLong.LongCodec {
@Override
- public int decodeInt(byte[] b, int o, SortOrder sortOrder) {
- throw new UnsupportedOperationException();
+ public Object getSampleValue(Integer maxLength, Integer arrayLength) {
+ return new Date((Long) PLong.INSTANCE.getSampleValue(maxLength, arrayLength));
}
- @Override
- public PhoenixArrayFactory getPhoenixArrayFactory() {
- return new PhoenixArrayFactory() {
+ static class DateCodec extends PLong.LongCodec {
+
+ @Override
+ public int decodeInt(byte[] b, int o, SortOrder sortOrder) {
+ throw new UnsupportedOperationException();
+ }
@Override
- public PhoenixArray newArray(PDataType type, Object[] elements) {
- return new PhoenixArray(type, elements);
+ public PhoenixArrayFactory getPhoenixArrayFactory() {
+ return new PhoenixArrayFactory() {
+
+ @Override
+ public PhoenixArray newArray(PDataType type, Object[] elements) {
+ return new PhoenixArray(type, elements);
+ }
+ };
}
- };
}
- }
}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/aa05da8a/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PDecimal.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PDecimal.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PDecimal.java
index ff6e186..17910de 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PDecimal.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PDecimal.java
@@ -28,6 +28,7 @@ import org.apache.phoenix.query.QueryConstants;
import org.apache.phoenix.schema.SortOrder;
import org.apache.phoenix.schema.TypeMismatchException;
import org.apache.phoenix.util.ByteUtil;
+import org.apache.phoenix.util.DateUtil;
import org.apache.phoenix.util.NumberUtil;
import com.google.common.base.Preconditions;
@@ -136,9 +137,8 @@ public class PDecimal extends PRealNumber<BigDecimal> {
return BigDecimal.valueOf(actualType.getCodec().decodeFloat(b, o, sortOrder));
} else if (equalsAny(actualType, PDouble.INSTANCE, PUnsignedDouble.INSTANCE)) {
return BigDecimal.valueOf(actualType.getCodec().decodeDouble(b, o, sortOrder));
- } else if (equalsAny(actualType, PTimestamp.INSTANCE,
- PUnsignedTimestamp.INSTANCE)) {
- long millisPart = actualType.getCodec().decodeLong(b, o, sortOrder);
+ } else if (equalsAny(actualType, PTimestamp.INSTANCE, PUnsignedTimestamp.INSTANCE)) {
+ long millisPart = DateUtil.getCodecFor(actualType).decodeLong(b, o, sortOrder);
int nanoPart = PUnsignedInt.INSTANCE.getCodec().decodeInt(b, o + Bytes.SIZEOF_LONG, sortOrder);
BigDecimal nanosPart = BigDecimal.valueOf(
(nanoPart % QueryConstants.MILLIS_TO_NANOS_CONVERTOR)
http://git-wip-us.apache.org/repos/asf/phoenix/blob/aa05da8a/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PLong.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PLong.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PLong.java
index 82fd8d3..2d6ff27 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PLong.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PLong.java
@@ -20,6 +20,7 @@ package org.apache.phoenix.schema.types;
import java.math.BigDecimal;
import java.sql.Types;
+import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.phoenix.schema.SortOrder;
@@ -29,304 +30,316 @@ import com.google.common.primitives.Longs;
public class PLong extends PWholeNumber<Long> {
- public static final PLong INSTANCE = new PLong();
+ public static final PLong INSTANCE = new PLong();
- private PLong() {
- super("BIGINT", Types.BIGINT, Long.class, new LongCodec(), 2);
- }
-
- @Override
- public Integer getScale(Object o) {
- return ZERO;
- }
-
- @Override
- public byte[] toBytes(Object object) {
- byte[] b = new byte[Bytes.SIZEOF_LONG];
- toBytes(object, b, 0);
- return b;
- }
-
- @Override
- public int toBytes(Object object, byte[] b, int o) {
- if (object == null) {
- throw newIllegalDataException(this + " may not be null");
+ private PLong() {
+ super("BIGINT", Types.BIGINT, Long.class, new LongCodec(), 2);
}
- return this.getCodec().encodeLong(((Number) object).longValue(), b, o);
- }
- @Override
- public Object toObject(Object object, PDataType actualType) {
- if (object == null) {
- return null;
- }
- long s;
- if (equalsAny(actualType, PLong.INSTANCE, PUnsignedLong.INSTANCE)) {
- return object;
- } else if (equalsAny(actualType, PUnsignedInt.INSTANCE,
- PInteger.INSTANCE)) {
- s = (Integer) object;
- return s;
- } else if (equalsAny(actualType, PTinyint.INSTANCE, PUnsignedTinyint.INSTANCE)) {
- s = (Byte) object;
- return s;
- } else if (equalsAny(actualType, PSmallint.INSTANCE, PUnsignedSmallint.INSTANCE)) {
- s = (Short) object;
- return s;
- } else if (equalsAny(actualType, PFloat.INSTANCE, PUnsignedFloat.INSTANCE)) {
- Float f = (Float) object;
- if (f > Long.MAX_VALUE || f < Long.MIN_VALUE) {
- throw newIllegalDataException(
- actualType + " value " + f + " cannot be cast to Long without changing its value");
- }
- s = f.longValue();
- return s;
- } else if (equalsAny(actualType, PDouble.INSTANCE, PUnsignedDouble.INSTANCE)) {
- Double de = (Double) object;
- if (de > Long.MAX_VALUE || de < Long.MIN_VALUE) {
- throw newIllegalDataException(
- actualType + " value " + de + " cannot be cast to Long without changing its value");
- }
- s = de.longValue();
- return s;
- } else if (actualType == PDecimal.INSTANCE) {
- BigDecimal d = (BigDecimal) object;
- return d.longValueExact();
- } else if (equalsAny(actualType, PDate.INSTANCE, PUnsignedDate.INSTANCE, PTime.INSTANCE,
- PUnsignedTime.INSTANCE)) {
- java.util.Date date = (java.util.Date) object;
- return date.getTime();
- }
- return throwConstraintViolationException(actualType, this);
- }
-
- @Override
- public Long toObject(byte[] b, int o, int l, PDataType actualType, SortOrder sortOrder,
- Integer maxLength, Integer scale) {
- if (l == 0) {
- return null;
- }
- if (equalsAny(actualType, PLong.INSTANCE, PUnsignedLong.INSTANCE,
- PInteger.INSTANCE, PUnsignedInt.INSTANCE, PSmallint.INSTANCE,
- PUnsignedSmallint.INSTANCE, PTinyint.INSTANCE, PUnsignedTinyint.INSTANCE, PFloat.INSTANCE,
- PUnsignedFloat.INSTANCE, PDouble.INSTANCE, PUnsignedDouble.INSTANCE, PDate.INSTANCE,
- PUnsignedDate.INSTANCE, PTime.INSTANCE, PUnsignedTime.INSTANCE)) {
- return actualType.getCodec().decodeLong(b, o, sortOrder);
- } else if (actualType == PDecimal.INSTANCE) {
- BigDecimal bd = (BigDecimal) actualType.toObject(b, o, l, actualType, sortOrder);
- return bd.longValueExact();
- }
- throwConstraintViolationException(actualType, this);
- return null;
- }
-
- @Override
- public boolean isCoercibleTo(PDataType targetType) {
- // In general, don't allow conversion of LONG to INTEGER. There are times when
- // we check isComparableTo for a more relaxed check and then throw a runtime
- // exception if we overflow
- return equalsAny(targetType, this, PDecimal.INSTANCE, PVarbinary.INSTANCE, PBinary.INSTANCE, PDouble.INSTANCE);
- }
-
- @Override
- public boolean isComparableTo(PDataType targetType) {
- return PDecimal.INSTANCE.isComparableTo(targetType);
- }
-
- @Override
- public boolean isCoercibleTo(PDataType targetType, Object value) {
- if (value != null) {
- long l;
- if (equalsAny(targetType, PUnsignedDouble.INSTANCE, PUnsignedFloat.INSTANCE,
- PUnsignedLong.INSTANCE)) {
- l = (Long) value;
- return l >= 0;
- } else if (targetType.equals(PUnsignedInt.INSTANCE)) {
- l = (Long) value;
- return (l >= 0 && l <= Integer.MAX_VALUE);
- } else if (targetType.equals(PInteger.INSTANCE)) {
- l = (Long) value;
- return (l >= Integer.MIN_VALUE && l <= Integer.MAX_VALUE);
- } else if (targetType.equals(PUnsignedSmallint.INSTANCE)) {
- l = (Long) value;
- return (l >= 0 && l <= Short.MAX_VALUE);
- } else if (targetType.equals(PSmallint.INSTANCE)) {
- l = (Long) value;
- return (l >= Short.MIN_VALUE && l <= Short.MAX_VALUE);
- } else if (targetType.equals(PTinyint.INSTANCE)) {
- l = (Long) value;
- return (l >= Byte.MIN_VALUE && l <= Byte.MAX_VALUE);
- } else if (targetType.equals(PUnsignedTinyint.INSTANCE)) {
- l = (Long) value;
- return (l >= 0 && l <= Byte.MAX_VALUE);
- }
- }
- return super.isCoercibleTo(targetType, value);
- }
-
- @Override
- public boolean isCastableTo(PDataType targetType) {
- return super.isCastableTo(targetType) || targetType.isCoercibleTo(PTimestamp.INSTANCE);
- }
-
- @Override
- public boolean isFixedWidth() {
- return true;
- }
-
- @Override
- public Integer getByteSize() {
- return Bytes.SIZEOF_LONG;
- }
-
- @Override
- public Integer getMaxLength(Object o) {
- return LONG_PRECISION;
- }
-
- @Override
- public int compareTo(Object lhs, Object rhs, PDataType rhsType) {
- if (rhsType == PDecimal.INSTANCE) {
- return -((BigDecimal) rhs).compareTo(BigDecimal.valueOf(((Number) lhs).longValue()));
- } else if (equalsAny(rhsType, PDouble.INSTANCE, PFloat.INSTANCE, PUnsignedDouble.INSTANCE, PUnsignedFloat.INSTANCE)) {
- return Doubles.compare(((Number) lhs).doubleValue(), ((Number) rhs).doubleValue());
+ @Override
+ public Integer getScale(Object o) {
+ return ZERO;
}
- return Longs.compare(((Number) lhs).longValue(), ((Number) rhs).longValue());
- }
- @Override
- public Object toObject(String value) {
- if (value == null || value.length() == 0) {
- return null;
- }
- try {
- return Long.parseLong(value);
- } catch (NumberFormatException e) {
- throw newIllegalDataException(e);
+ @Override
+ public byte[] toBytes(Object object) {
+ byte[] b = new byte[Bytes.SIZEOF_LONG];
+ toBytes(object, b, 0);
+ return b;
}
- }
- @Override
- public Object getSampleValue(Integer maxLength, Integer arrayLength) {
- return RANDOM.get().nextLong();
- }
+ @Override
+ public int toBytes(Object object, byte[] b, int o) {
+ if (object == null) {
+ throw newIllegalDataException(this + " may not be null");
+ }
+ return this.getCodec().encodeLong(((Number) object).longValue(), b, o);
+ }
- static class LongCodec extends BaseCodec {
+ @Override
+ public Object toObject(Object object, PDataType actualType) {
+ if (object == null) {
+ return null;
+ }
+ long s;
+ if (equalsAny(actualType, PLong.INSTANCE, PUnsignedLong.INSTANCE)) {
+ return object;
+ } else if (equalsAny(actualType, PUnsignedInt.INSTANCE,
+ PInteger.INSTANCE)) {
+ s = (Integer) object;
+ return s;
+ } else if (equalsAny(actualType, PTinyint.INSTANCE, PUnsignedTinyint.INSTANCE)) {
+ s = (Byte) object;
+ return s;
+ } else if (equalsAny(actualType, PSmallint.INSTANCE, PUnsignedSmallint.INSTANCE)) {
+ s = (Short) object;
+ return s;
+ } else if (equalsAny(actualType, PFloat.INSTANCE, PUnsignedFloat.INSTANCE)) {
+ Float f = (Float) object;
+ if (f > Long.MAX_VALUE || f < Long.MIN_VALUE) {
+ throw newIllegalDataException(
+ actualType + " value " + f + " cannot be cast to Long without changing its value");
+ }
+ s = f.longValue();
+ return s;
+ } else if (equalsAny(actualType, PDouble.INSTANCE, PUnsignedDouble.INSTANCE)) {
+ Double de = (Double) object;
+ if (de > Long.MAX_VALUE || de < Long.MIN_VALUE) {
+ throw newIllegalDataException(
+ actualType + " value " + de + " cannot be cast to Long without changing its value");
+ }
+ s = de.longValue();
+ return s;
+ } else if (actualType == PDecimal.INSTANCE) {
+ BigDecimal d = (BigDecimal) object;
+ return d.longValueExact();
+ } else if (equalsAny(actualType, PDate.INSTANCE, PUnsignedDate.INSTANCE, PTime.INSTANCE,
+ PUnsignedTime.INSTANCE)) {
+ java.util.Date date = (java.util.Date) object;
+ return date.getTime();
+ }
+ return throwConstraintViolationException(actualType, this);
+ }
@Override
- public float decodeFloat(byte[] b, int o, SortOrder sortOrder) {
- return decodeLong(b, o, sortOrder);
+ public Long toObject(byte[] b, int o, int l, PDataType actualType, SortOrder sortOrder,
+ Integer maxLength, Integer scale) {
+ if (l == 0) {
+ return null;
+ }
+ if (equalsAny(actualType, PLong.INSTANCE, PUnsignedLong.INSTANCE,
+ PInteger.INSTANCE, PUnsignedInt.INSTANCE, PSmallint.INSTANCE,
+ PUnsignedSmallint.INSTANCE, PTinyint.INSTANCE, PUnsignedTinyint.INSTANCE, PFloat.INSTANCE,
+ PUnsignedFloat.INSTANCE, PDouble.INSTANCE, PUnsignedDouble.INSTANCE, PDate.INSTANCE,
+ PUnsignedDate.INSTANCE, PTime.INSTANCE, PUnsignedTime.INSTANCE)) {
+ return actualType.getCodec().decodeLong(b, o, sortOrder);
+ } else if (actualType == PDecimal.INSTANCE) {
+ BigDecimal bd = (BigDecimal) actualType.toObject(b, o, l, actualType, sortOrder);
+ return bd.longValueExact();
+ }
+ throwConstraintViolationException(actualType, this);
+ return null;
}
@Override
- public double decodeDouble(byte[] b, int o, SortOrder sortOrder) {
- return decodeLong(b, o, sortOrder);
+ public boolean isCoercibleTo(PDataType targetType) {
+ // In general, don't allow conversion of LONG to INTEGER. There are times when
+ // we check isComparableTo for a more relaxed check and then throw a runtime
+ // exception if we overflow
+ return equalsAny(targetType, this, PDecimal.INSTANCE, PVarbinary.INSTANCE, PBinary.INSTANCE, PDouble.INSTANCE);
}
@Override
- public long decodeLong(byte[] bytes, int o, SortOrder sortOrder) {
- Preconditions.checkNotNull(sortOrder);
- checkForSufficientLength(bytes, o, Bytes.SIZEOF_LONG);
- long v;
- byte b = bytes[o];
- if (sortOrder == SortOrder.ASC) {
- v = b ^ 0x80; // Flip sign bit back
- for (int i = 1; i < Bytes.SIZEOF_LONG; i++) {
- b = bytes[o + i];
- v = (v << 8) + (b & 0xff);
+ public void coerceBytes(ImmutableBytesWritable ptr, Object object, PDataType actualType,
+ Integer maxLength, Integer scale, SortOrder actualModifier, Integer desiredMaxLength, Integer desiredScale,
+ SortOrder expectedModifier) {
+ // Decrease size of TIMESTAMP to size of LONG and continue coerce
+ if (ptr.getLength() > getByteSize()) {
+ ptr.set(ptr.get(), ptr.getOffset(), getByteSize());
}
- } else {
- b = (byte) (b ^ 0xff);
- v = b ^ 0x80; // Flip sign bit back
- for (int i = 1; i < Bytes.SIZEOF_LONG; i++) {
- b = bytes[o + i];
- b ^= 0xff;
- v = (v << 8) + (b & 0xff);
- }
- }
- return v;
+ super.coerceBytes(ptr, object, actualType, maxLength, scale, actualModifier, desiredMaxLength,
+ desiredScale, expectedModifier);
}
@Override
- public int decodeInt(byte[] b, int o, SortOrder sortOrder) {
- long v = decodeLong(b, o, sortOrder);
- if (v < Integer.MIN_VALUE || v > Integer.MAX_VALUE) {
- throw newIllegalDataException(
- "Value " + v + " cannot be cast to Integer without changing its value");
- }
- return (int) v;
+ public boolean isComparableTo(PDataType targetType) {
+ return PDecimal.INSTANCE.isComparableTo(targetType);
}
@Override
- public int encodeFloat(float v, byte[] b, int o) {
- if (v < Long.MIN_VALUE || v > Long.MAX_VALUE) {
- throw newIllegalDataException(
- "Value " + v + " cannot be encoded as an Long without changing its value");
- }
- return encodeLong((long) v, b, o);
+ public boolean isCoercibleTo(PDataType targetType, Object value) {
+ if (value != null) {
+ long l;
+ if (equalsAny(targetType, PUnsignedDouble.INSTANCE, PUnsignedFloat.INSTANCE,
+ PUnsignedLong.INSTANCE)) {
+ l = (Long) value;
+ return l >= 0;
+ } else if (targetType.equals(PUnsignedInt.INSTANCE)) {
+ l = (Long) value;
+ return (l >= 0 && l <= Integer.MAX_VALUE);
+ } else if (targetType.equals(PInteger.INSTANCE)) {
+ l = (Long) value;
+ return (l >= Integer.MIN_VALUE && l <= Integer.MAX_VALUE);
+ } else if (targetType.equals(PUnsignedSmallint.INSTANCE)) {
+ l = (Long) value;
+ return (l >= 0 && l <= Short.MAX_VALUE);
+ } else if (targetType.equals(PSmallint.INSTANCE)) {
+ l = (Long) value;
+ return (l >= Short.MIN_VALUE && l <= Short.MAX_VALUE);
+ } else if (targetType.equals(PTinyint.INSTANCE)) {
+ l = (Long) value;
+ return (l >= Byte.MIN_VALUE && l <= Byte.MAX_VALUE);
+ } else if (targetType.equals(PUnsignedTinyint.INSTANCE)) {
+ l = (Long) value;
+ return (l >= 0 && l <= Byte.MAX_VALUE);
+ }
+ }
+ return super.isCoercibleTo(targetType, value);
}
@Override
- public int encodeDouble(double v, byte[] b, int o) {
- if (v < Long.MIN_VALUE || v > Long.MAX_VALUE) {
- throw newIllegalDataException(
- "Value " + v + " cannot be encoded as an Long without changing its value");
- }
- return encodeLong((long) v, b, o);
+ public boolean isCastableTo(PDataType targetType) {
+ return super.isCastableTo(targetType) || targetType.isCoercibleTo(PTimestamp.INSTANCE);
}
@Override
- public int encodeLong(long v, byte[] b, int o) {
- checkForSufficientLength(b, o, Bytes.SIZEOF_LONG);
- b[o + 0] = (byte) ((v >> 56) ^ 0x80); // Flip sign bit so that INTEGER is binary comparable
- b[o + 1] = (byte) (v >> 48);
- b[o + 2] = (byte) (v >> 40);
- b[o + 3] = (byte) (v >> 32);
- b[o + 4] = (byte) (v >> 24);
- b[o + 5] = (byte) (v >> 16);
- b[o + 6] = (byte) (v >> 8);
- b[o + 7] = (byte) v;
- return Bytes.SIZEOF_LONG;
+ public boolean isFixedWidth() {
+ return true;
}
@Override
- public byte decodeByte(byte[] b, int o, SortOrder sortOrder) {
- long v = decodeLong(b, o, sortOrder);
- if (v < Byte.MIN_VALUE || v > Byte.MAX_VALUE) {
- throw newIllegalDataException(
- "Value " + v + " cannot be cast to Byte without changing its value");
- }
- return (byte) v;
+ public Integer getByteSize() {
+ return Bytes.SIZEOF_LONG;
}
@Override
- public short decodeShort(byte[] b, int o, SortOrder sortOrder) {
- long v = decodeLong(b, o, sortOrder);
- if (v < Short.MIN_VALUE || v > Short.MAX_VALUE) {
- throw newIllegalDataException(
- "Value " + v + " cannot be cast to Short without changing its value");
- }
- return (short) v;
+ public Integer getMaxLength(Object o) {
+ return LONG_PRECISION;
}
@Override
- public int encodeByte(byte v, byte[] b, int o) {
- return encodeLong(v, b, o);
+ public int compareTo(Object lhs, Object rhs, PDataType rhsType) {
+ if (rhsType == PDecimal.INSTANCE) {
+ return -((BigDecimal) rhs).compareTo(BigDecimal.valueOf(((Number) lhs).longValue()));
+ } else if (equalsAny(rhsType, PDouble.INSTANCE, PFloat.INSTANCE, PUnsignedDouble.INSTANCE, PUnsignedFloat.INSTANCE)) {
+ return Doubles.compare(((Number) lhs).doubleValue(), ((Number) rhs).doubleValue());
+ }
+ return Longs.compare(((Number) lhs).longValue(), ((Number) rhs).longValue());
}
@Override
- public int encodeShort(short v, byte[] b, int o) {
- return encodeLong(v, b, o);
+ public Object toObject(String value) {
+ if (value == null || value.length() == 0) {
+ return null;
+ }
+ try {
+ return Long.parseLong(value);
+ } catch (NumberFormatException e) {
+ throw newIllegalDataException(e);
+ }
}
@Override
- public PhoenixArrayFactory getPhoenixArrayFactory() {
- return new PhoenixArrayFactory() {
+ public Object getSampleValue(Integer maxLength, Integer arrayLength) {
+ return RANDOM.get().nextLong();
+ }
+
+ static class LongCodec extends BaseCodec {
+
+ @Override
+ public float decodeFloat(byte[] b, int o, SortOrder sortOrder) {
+ return decodeLong(b, o, sortOrder);
+ }
+
+ @Override
+ public double decodeDouble(byte[] b, int o, SortOrder sortOrder) {
+ return decodeLong(b, o, sortOrder);
+ }
+
+ @Override
+ public long decodeLong(byte[] bytes, int o, SortOrder sortOrder) {
+ Preconditions.checkNotNull(sortOrder);
+ checkForSufficientLength(bytes, o, Bytes.SIZEOF_LONG);
+ long v;
+ byte b = bytes[o];
+ if (sortOrder == SortOrder.ASC) {
+ v = b ^ 0x80; // Flip sign bit back
+ for (int i = 1; i < Bytes.SIZEOF_LONG; i++) {
+ b = bytes[o + i];
+ v = (v << 8) + (b & 0xff);
+ }
+ } else {
+ b = (byte) (b ^ 0xff);
+ v = b ^ 0x80; // Flip sign bit back
+ for (int i = 1; i < Bytes.SIZEOF_LONG; i++) {
+ b = bytes[o + i];
+ b ^= 0xff;
+ v = (v << 8) + (b & 0xff);
+ }
+ }
+ return v;
+ }
+
+ @Override
+ public int decodeInt(byte[] b, int o, SortOrder sortOrder) {
+ long v = decodeLong(b, o, sortOrder);
+ if (v < Integer.MIN_VALUE || v > Integer.MAX_VALUE) {
+ throw newIllegalDataException(
+ "Value " + v + " cannot be cast to Integer without changing its value");
+ }
+ return (int) v;
+ }
+
+ @Override
+ public int encodeFloat(float v, byte[] b, int o) {
+ if (v < Long.MIN_VALUE || v > Long.MAX_VALUE) {
+ throw newIllegalDataException(
+ "Value " + v + " cannot be encoded as an Long without changing its value");
+ }
+ return encodeLong((long) v, b, o);
+ }
+
+ @Override
+ public int encodeDouble(double v, byte[] b, int o) {
+ if (v < Long.MIN_VALUE || v > Long.MAX_VALUE) {
+ throw newIllegalDataException(
+ "Value " + v + " cannot be encoded as an Long without changing its value");
+ }
+ return encodeLong((long) v, b, o);
+ }
+
+ @Override
+ public int encodeLong(long v, byte[] b, int o) {
+ checkForSufficientLength(b, o, Bytes.SIZEOF_LONG);
+ b[o + 0] = (byte) ((v >> 56) ^ 0x80); // Flip sign bit so that INTEGER is binary comparable
+ b[o + 1] = (byte) (v >> 48);
+ b[o + 2] = (byte) (v >> 40);
+ b[o + 3] = (byte) (v >> 32);
+ b[o + 4] = (byte) (v >> 24);
+ b[o + 5] = (byte) (v >> 16);
+ b[o + 6] = (byte) (v >> 8);
+ b[o + 7] = (byte) v;
+ return Bytes.SIZEOF_LONG;
+ }
+
+ @Override
+ public byte decodeByte(byte[] b, int o, SortOrder sortOrder) {
+ long v = decodeLong(b, o, sortOrder);
+ if (v < Byte.MIN_VALUE || v > Byte.MAX_VALUE) {
+ throw newIllegalDataException(
+ "Value " + v + " cannot be cast to Byte without changing its value");
+ }
+ return (byte) v;
+ }
+
+ @Override
+ public short decodeShort(byte[] b, int o, SortOrder sortOrder) {
+ long v = decodeLong(b, o, sortOrder);
+ if (v < Short.MIN_VALUE || v > Short.MAX_VALUE) {
+ throw newIllegalDataException(
+ "Value " + v + " cannot be cast to Short without changing its value");
+ }
+ return (short) v;
+ }
+
+ @Override
+ public int encodeByte(byte v, byte[] b, int o) {
+ return encodeLong(v, b, o);
+ }
+
+ @Override
+ public int encodeShort(short v, byte[] b, int o) {
+ return encodeLong(v, b, o);
+ }
+
@Override
- public PhoenixArray newArray(PDataType type, Object[] elements) {
- return new PhoenixArray.PrimitiveLongPhoenixArray(type, elements);
+ public PhoenixArrayFactory getPhoenixArrayFactory() {
+ return new PhoenixArrayFactory() {
+ @Override
+ public PhoenixArray newArray(PDataType type, Object[] elements) {
+ return new PhoenixArray.PrimitiveLongPhoenixArray(type, elements);
+ }
+ };
}
- };
}
- }
}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/aa05da8a/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PTime.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PTime.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PTime.java
index 0cfb0e8..03afae9 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PTime.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PTime.java
@@ -123,7 +123,7 @@ public class PTime extends PDataType<Time> {
@Override
public boolean isBytesComparableWith(PDataType otherType) {
- return super.isBytesComparableWith(otherType) || otherType.equals(PDate.INSTANCE);
+ return super.isBytesComparableWith(otherType) || otherType == PDate.INSTANCE || otherType == PTimestamp.INSTANCE || otherType == PLong.INSTANCE;
}
@Override
http://git-wip-us.apache.org/repos/asf/phoenix/blob/aa05da8a/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 cdfb533..c35a039 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
@@ -31,13 +31,19 @@ import org.apache.phoenix.schema.SortOrder;
import org.apache.phoenix.util.ByteUtil;
import org.apache.phoenix.util.DateUtil;
+import com.google.common.base.Preconditions;
+
public class PTimestamp extends PDataType<Timestamp> {
public static final int MAX_NANOS_VALUE_EXCLUSIVE = 1000000;
public static final PTimestamp INSTANCE = new PTimestamp();
+ protected PTimestamp(String sqlTypeName, int sqlType, int ordinal) {
+ super(sqlTypeName, sqlType, java.sql.Timestamp.class, null, ordinal);
+ }
+
private PTimestamp() {
super("TIMESTAMP", Types.TIMESTAMP, java.sql.Timestamp.class,
- new PDate.DateCodec(), 9);
+ null, 9);
}
@Override
@@ -48,6 +54,28 @@ public class PTimestamp extends PDataType<Timestamp> {
}
@Override
+ public void coerceBytes(ImmutableBytesWritable ptr, Object o, PDataType actualType, Integer actualMaxLength,
+ Integer actualScale, SortOrder actualModifier, Integer desiredMaxLength, Integer desiredScale,
+ SortOrder expectedModifier) {
+ Preconditions.checkNotNull(actualModifier);
+ Preconditions.checkNotNull(expectedModifier);
+ if (ptr.getLength() == 0) { return; }
+ if (this.isBytesComparableWith(actualType)) { // No coerce necessary
+ if (actualModifier != expectedModifier || (actualType.isFixedWidth() && actualType.getByteSize() < this.getByteSize())) {
+ byte[] b = new byte[this.getByteSize()];
+ System.arraycopy(ptr.get(), ptr.getOffset(), b, 0, actualType.getByteSize());
+ ptr.set(b);
+
+ if (actualModifier != expectedModifier) {
+ SortOrder.invert(b, 0, b, 0, b.length);
+ }
+ }
+ return;
+ }
+ super.coerceBytes(ptr, o, actualType, actualMaxLength, actualScale, actualModifier, desiredMaxLength, desiredScale, expectedModifier);
+ }
+
+ @Override
public int toBytes(Object object, byte[] bytes, int offset) {
if (object == null) {
// Create the byte[] of size MAX_TIMESTAMP_BYTES
@@ -61,7 +89,7 @@ public class PTimestamp extends PDataType<Timestamp> {
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);
+ DateUtil.getCodecFor(this).encodeLong(value.getTime(), bytes, offset);
/*
* By not getting the stuff that got spilled over from the millis part,
@@ -73,6 +101,11 @@ public class PTimestamp extends PDataType<Timestamp> {
}
@Override
+ public boolean isBytesComparableWith(PDataType otherType) {
+ return super.isBytesComparableWith(otherType) || otherType == PTime.INSTANCE || otherType == PDate.INSTANCE || otherType == PLong.INSTANCE;
+ }
+
+ @Override
public Object toObject(Object object, PDataType actualType) {
if (object == null) {
return null;
@@ -106,8 +139,7 @@ public class PTimestamp extends PDataType<Timestamp> {
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);
+ DateUtil.getCodecFor(actualType).decodeLong(b, o, sortOrder);
v = new java.sql.Timestamp(millisDeserialized);
int nanosDeserialized =
PUnsignedInt.INSTANCE.getCodec().decodeInt(b, o + Bytes.SIZEOF_LONG, sortOrder);
@@ -205,7 +237,7 @@ public class PTimestamp extends PDataType<Timestamp> {
@Override
public long getMillis(ImmutableBytesWritable ptr, SortOrder sortOrder) {
- long millis = PLong.INSTANCE.getCodec().decodeLong(ptr.get(), ptr.getOffset(), sortOrder);
+ long millis = DateUtil.getCodecFor(this).decodeLong(ptr.get(), ptr.getOffset(), sortOrder);
return millis;
}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/aa05da8a/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PUnsignedDate.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PUnsignedDate.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PUnsignedDate.java
index a6b1bc3..863b0d1 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PUnsignedDate.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/types/PUnsignedDate.java
@@ -27,138 +27,137 @@ import org.apache.phoenix.util.DateUtil;
public class PUnsignedDate extends PDataType<Date> {
- public static final PUnsignedDate INSTANCE = new PUnsignedDate();
-
- private PUnsignedDate() {
- super("UNSIGNED_DATE", 19, Date.class,
- new UnsignedDateCodec(), 14); // After TIMESTAMP and DATE to ensure toLiteral finds those first
- }
-
- @Override
- public byte[] toBytes(Object object) {
- if (object == null) {
- throw newIllegalDataException(this + " may not be null");
- }
- byte[] bytes = new byte[getByteSize()];
- toBytes(object, bytes, 0);
- return bytes;
- }
-
- @Override
- public int toBytes(Object object, byte[] bytes, int offset) {
- if (object == null) {
- throw newIllegalDataException(this + " may not be null");
- }
- getCodec().encodeLong(((java.util.Date) object).getTime(), bytes, offset);
- return this.getByteSize();
- }
-
- @Override
- public Object toObject(Object object, PDataType actualType) {
- Date d = (Date) PDate.INSTANCE.toObject(object, actualType);
- throwIfNonNegativeDate(d);
- return d;
- }
-
- @Override
- public Object toObject(byte[] b, int o, int l, PDataType actualType, SortOrder sortOrder, Integer maxLength, Integer scale) {
- Date d = (Date) PDate.INSTANCE.toObject(b, o, l, actualType, sortOrder);
- throwIfNonNegativeDate(d);
- return d;
- }
-
- @Override
- public boolean isCastableTo(PDataType targetType) {
- return PDate.INSTANCE.isCastableTo(targetType);
- }
-
- @Override
- public boolean isCoercibleTo(PDataType targetType) {
- return equalsAny(targetType, this, PUnsignedTime.INSTANCE, PUnsignedTimestamp.INSTANCE)
- || PDate.INSTANCE.isCoercibleTo(targetType);
- }
-
- @Override
- public boolean isCoercibleTo(PDataType targetType, Object value) {
- return super.isCoercibleTo(targetType, value) || PDate.INSTANCE.isCoercibleTo(targetType, value);
- }
-
- @Override
- public boolean isFixedWidth() {
- return true;
- }
-
- @Override
- public Integer getByteSize() {
- return PDate.INSTANCE.getByteSize();
- }
-
- @Override
- public int compareTo(Object lhs, Object rhs, PDataType rhsType) {
- return PDate.INSTANCE.compareTo(lhs, rhs, rhsType);
- }
-
- @Override
- public Object toObject(String value) {
- return PDate.INSTANCE.toObject(value);
- }
-
- @Override
- public boolean isBytesComparableWith(PDataType otherType) {
- return super.isBytesComparableWith(otherType) || otherType.equals(PUnsignedTime.INSTANCE);
- }
-
- @Override
- public String toStringLiteral(Object o, Format formatter) {
- // Can't delegate, as the super.toStringLiteral calls this.toBytes
- if (formatter == null || formatter == DateUtil.DEFAULT_DATE_FORMATTER) {
- // If default formatter has not been overridden,
- // use one that displays milliseconds.
- formatter = DateUtil.DEFAULT_MS_DATE_FORMATTER;
- }
- return "'" + super.toStringLiteral(o, formatter) + "'";
- }
-
- @Override
- public void coerceBytes(ImmutableBytesWritable ptr, Object object, PDataType actualType,
- Integer maxLength, Integer scale, SortOrder actualModifier,
- Integer desiredMaxLength, Integer desiredScale,
- SortOrder expectedModifier) {
- if (ptr.getLength() > 0 && actualType == PUnsignedTimestamp.INSTANCE
- && actualModifier == expectedModifier) {
- ptr.set(ptr.get(), ptr.getOffset(), getByteSize());
- return;
- }
- super.coerceBytes(ptr, object, actualType, maxLength, scale, actualModifier, desiredMaxLength,
- desiredScale, expectedModifier);
- }
-
- @Override
- public int getResultSetSqlType() {
- return Types.DATE;
- }
-
- @Override
- public Object getSampleValue(Integer maxLength, Integer arrayLength) {
- return new Date((Long) PUnsignedLong.INSTANCE.getSampleValue(maxLength, arrayLength));
- }
-
- static class UnsignedDateCodec extends PUnsignedLong.UnsignedLongCodec {
-
- @Override
- public int decodeInt(byte[] b, int o, SortOrder sortOrder) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public PhoenixArrayFactory getPhoenixArrayFactory() {
- return new PhoenixArrayFactory() {
+ public static final PUnsignedDate INSTANCE = new PUnsignedDate();
+
+ private PUnsignedDate() {
+ super("UNSIGNED_DATE", 19, Date.class,
+ new UnsignedDateCodec(), 14); // After TIMESTAMP and DATE to ensure toLiteral finds those first
+ }
+
+ @Override
+ public byte[] toBytes(Object object) {
+ if (object == null) {
+ throw newIllegalDataException(this + " may not be null");
+ }
+ byte[] bytes = new byte[getByteSize()];
+ toBytes(object, bytes, 0);
+ return bytes;
+ }
+
+ @Override
+ public int toBytes(Object object, byte[] bytes, int offset) {
+ if (object == null) {
+ throw newIllegalDataException(this + " may not be null");
+ }
+ getCodec().encodeLong(((java.util.Date) object).getTime(), bytes, offset);
+ return this.getByteSize();
+ }
+
+ @Override
+ public Object toObject(Object object, PDataType actualType) {
+ Date d = (Date) PDate.INSTANCE.toObject(object, actualType);
+ throwIfNonNegativeDate(d);
+ return d;
+ }
+
+ @Override
+ public Object toObject(byte[] b, int o, int l, PDataType actualType, SortOrder sortOrder, Integer maxLength, Integer scale) {
+ Date d = (Date) PDate.INSTANCE.toObject(b, o, l, actualType, sortOrder);
+ throwIfNonNegativeDate(d);
+ return d;
+ }
+
+ @Override
+ public boolean isCastableTo(PDataType targetType) {
+ return PDate.INSTANCE.isCastableTo(targetType);
+ }
+
+ @Override
+ public boolean isCoercibleTo(PDataType targetType) {
+ return equalsAny(targetType, this, PUnsignedTime.INSTANCE, PUnsignedTimestamp.INSTANCE)
+ || PDate.INSTANCE.isCoercibleTo(targetType);
+ }
+
+ @Override
+ public boolean isCoercibleTo(PDataType targetType, Object value) {
+ return super.isCoercibleTo(targetType, value) || PDate.INSTANCE.isCoercibleTo(targetType, value);
+ }
+
+ @Override
+ public boolean isFixedWidth() {
+ return true;
+ }
+
+ @Override
+ public Integer getByteSize() {
+ return PDate.INSTANCE.getByteSize();
+ }
+
+ @Override
+ public int compareTo(Object lhs, Object rhs, PDataType rhsType) {
+ return PDate.INSTANCE.compareTo(lhs, rhs, rhsType);
+ }
+
+ @Override
+ public Object toObject(String value) {
+ return PDate.INSTANCE.toObject(value);
+ }
+
+ @Override
+ public boolean isBytesComparableWith(PDataType otherType) {
+ return super.isBytesComparableWith(otherType) || otherType == PUnsignedTime.INSTANCE || otherType == PUnsignedTimestamp.INSTANCE || otherType == PUnsignedLong.INSTANCE;
+ }
+
+ @Override
+ public String toStringLiteral(Object o, Format formatter) {
+ // Can't delegate, as the super.toStringLiteral calls this.toBytes
+ if (formatter == null || formatter == DateUtil.DEFAULT_DATE_FORMATTER) {
+ // If default formatter has not been overridden,
+ // use one that displays milliseconds.
+ formatter = DateUtil.DEFAULT_MS_DATE_FORMATTER;
+ }
+ return "'" + super.toStringLiteral(o, formatter) + "'";
+ }
+
+ // TODO: derive PUnsignedDate from PDate to avoid copy/paste
+ @Override
+ public void coerceBytes(ImmutableBytesWritable ptr, Object object, PDataType actualType,
+ Integer maxLength, Integer scale, SortOrder actualModifier,
+ Integer desiredMaxLength, Integer desiredScale,
+ SortOrder expectedModifier) {
+ if (ptr.getLength() > getByteSize()) {
+ ptr.set(ptr.get(), ptr.getOffset(), getByteSize());
+ }
+ super.coerceBytes(ptr, object, actualType, maxLength, scale, actualModifier, desiredMaxLength,
+ desiredScale, expectedModifier);
+ }
+
+ @Override
+ public int getResultSetSqlType() {
+ return Types.DATE;
+ }
+
+ @Override
+ public Object getSampleValue(Integer maxLength, Integer arrayLength) {
+ return new Date((Long) PUnsignedLong.INSTANCE.getSampleValue(maxLength, arrayLength));
+ }
+
+ static class UnsignedDateCodec extends PUnsignedLong.UnsignedLongCodec {
+
+ @Override
+ public int decodeInt(byte[] b, int o, SortOrder sortOrder) {
+ throw new UnsupportedOperationException();
+ }
@Override
- public PhoenixArray newArray(PDataType type, Object[] elements) {
- return new PhoenixArray(type, elements);
+ public PhoenixArrayFactory getPhoenixArrayFactory() {
+ return new PhoenixArrayFactory() {
+
+ @Override
+ public PhoenixArray newArray(PDataType type, Object[] elements) {
+ return new PhoenixArray(type, elements);
+ }
+ };
}
- };
}
- }
}