You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@phoenix.apache.org by gr...@apache.org on 2014/12/21 09:36:59 UTC
phoenix git commit: PHOENIX-1127 Support milliseconds in timestamp
parsing
Repository: phoenix
Updated Branches:
refs/heads/3.0 9cd65bf0a -> ddeacbf78
PHOENIX-1127 Support milliseconds in timestamp parsing
Use Joda time for (implicit) date parsing, allowing date-time
values to contain an optional time component, as well as supporting
optional millisecond parsing.
Project: http://git-wip-us.apache.org/repos/asf/phoenix/repo
Commit: http://git-wip-us.apache.org/repos/asf/phoenix/commit/ddeacbf7
Tree: http://git-wip-us.apache.org/repos/asf/phoenix/tree/ddeacbf7
Diff: http://git-wip-us.apache.org/repos/asf/phoenix/diff/ddeacbf7
Branch: refs/heads/3.0
Commit: ddeacbf78fbed11ddd7409e01920d9d198d40404
Parents: 9cd65bf
Author: Gabriel Reid <gr...@apache.org>
Authored: Sat Dec 20 18:03:58 2014 +0100
Committer: Gabriel Reid <gr...@apache.org>
Committed: Sun Dec 21 09:34:19 2014 +0100
----------------------------------------------------------------------
.../src/build/components-major-client.xml | 1 +
phoenix-core/pom.xml | 4 ++
.../phoenix/end2end/CSVCommonsLoaderIT.java | 41 ++++++++++++++
.../java/org/apache/phoenix/util/DateUtil.java | 57 ++++++++------------
.../org/apache/phoenix/util/DateUtilTest.java | 42 +++++++++++++++
5 files changed, 110 insertions(+), 35 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/phoenix/blob/ddeacbf7/phoenix-assembly/src/build/components-major-client.xml
----------------------------------------------------------------------
diff --git a/phoenix-assembly/src/build/components-major-client.xml b/phoenix-assembly/src/build/components-major-client.xml
index c3980cd..ca6e9db 100644
--- a/phoenix-assembly/src/build/components-major-client.xml
+++ b/phoenix-assembly/src/build/components-major-client.xml
@@ -49,6 +49,7 @@
<include>org.codehaus.jackson:jackson-mapper-asl</include>
<include>org.codehaus.jackson:jackson-core-asl</include>
<include>org.xerial.snappy:snappy-java</include>
+ <include>joda-time:joda-time</include>
</includes>
</dependencySet>
</dependencySets>
http://git-wip-us.apache.org/repos/asf/phoenix/blob/ddeacbf7/phoenix-core/pom.xml
----------------------------------------------------------------------
diff --git a/phoenix-core/pom.xml b/phoenix-core/pom.xml
index fceb6c7..6098443 100644
--- a/phoenix-core/pom.xml
+++ b/phoenix-core/pom.xml
@@ -237,6 +237,10 @@
<groupId>org.apache.hbase</groupId>
<artifactId>hbase</artifactId>
</dependency>
+ <dependency>
+ <groupId>joda-time</groupId>
+ <artifactId>joda-time</artifactId>
+ </dependency>
<!-- Findbugs Annotation -->
<dependency>
<groupId>net.sourceforge.findbugs</groupId>
http://git-wip-us.apache.org/repos/asf/phoenix/blob/ddeacbf7/phoenix-core/src/it/java/org/apache/phoenix/end2end/CSVCommonsLoaderIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/CSVCommonsLoaderIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/CSVCommonsLoaderIT.java
index e98d5f3..1cc5ff6 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/CSVCommonsLoaderIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/CSVCommonsLoaderIT.java
@@ -651,6 +651,47 @@ public class CSVCommonsLoaderIT extends BaseHBaseManagedTimeIT {
}
@Test
+ public void testCSVCommonsUpsert_WithTimestamp() throws Exception {
+ CSVParser parser = null;
+ PhoenixConnection conn = null;
+ try {
+
+ // Create table
+ String statements = "CREATE TABLE IF NOT EXISTS TS_TABLE "
+ + "(ID BIGINT NOT NULL PRIMARY KEY, TS TIMESTAMP);";
+ conn = DriverManager.getConnection(getUrl()).unwrap(
+ PhoenixConnection.class);
+ PhoenixRuntime.executeStatements(conn,
+ new StringReader(statements), null);
+
+ // Upsert CSV file
+ CSVCommonsLoader csvUtil = new CSVCommonsLoader(conn, "TS_TABLE",
+ null, true, ',', '"', null, "!");
+ csvUtil.upsert(
+ new StringReader("ID,TS\n"
+ + "1,1970-01-01 00:00:10\n"
+ + "2,1970-01-01 00:00:10.123\n"));
+
+ // Compare Phoenix ResultSet with CSV file content
+ PreparedStatement statement = conn
+ .prepareStatement("SELECT ID, TS FROM TS_TABLE ORDER BY ID");
+ ResultSet phoenixResultSet = statement.executeQuery();
+ assertTrue(phoenixResultSet.next());
+ assertEquals(1L, phoenixResultSet.getLong(1));
+ assertEquals(10000L, phoenixResultSet.getTimestamp(2).getTime());
+ assertTrue(phoenixResultSet.next());
+ assertEquals(2L, phoenixResultSet.getLong(1));
+ assertEquals(10123L, phoenixResultSet.getTimestamp(2).getTime());
+ assertFalse(phoenixResultSet.next());
+ } finally {
+ if (parser != null)
+ parser.close();
+ if (conn != null)
+ conn.close();
+ }
+ }
+
+ @Test
public void testCSVCommonsUpsert_NonExistentTable() throws Exception {
PhoenixConnection conn = null;
try {
http://git-wip-us.apache.org/repos/asf/phoenix/blob/ddeacbf7/phoenix-core/src/main/java/org/apache/phoenix/util/DateUtil.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/util/DateUtil.java b/phoenix-core/src/main/java/org/apache/phoenix/util/DateUtil.java
index c940067..8952708 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/util/DateUtil.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/util/DateUtil.java
@@ -30,7 +30,11 @@ import org.apache.commons.lang.time.FastDateFormat;
import org.apache.phoenix.query.QueryConstants;
import org.apache.phoenix.schema.IllegalDataException;
-
+import org.joda.time.DateTime;
+import org.joda.time.chrono.ISOChronology;
+import org.joda.time.format.DateTimeFormatter;
+import org.joda.time.format.DateTimeFormatterBuilder;
+import org.joda.time.format.ISODateTimeFormat;
@SuppressWarnings("serial")
@@ -45,6 +49,14 @@ public class DateUtil {
public static final Format DEFAULT_MS_DATE_FORMATTER = FastDateFormat.getInstance(
DEFAULT_MS_DATE_FORMAT, TimeZone.getTimeZone(DEFAULT_TIME_ZONE_ID));
+ private static final DateTimeFormatter DATE_TIME_PARSER = new DateTimeFormatterBuilder()
+ .append(ISODateTimeFormat.dateParser())
+ .appendOptional(new DateTimeFormatterBuilder()
+ .appendLiteral(' ')
+ .append(ISODateTimeFormat.timeParser()).toParser())
+ .toFormatter()
+ .withChronology(ISOChronology.getInstanceUTC());
+
private DateUtil() {
}
@@ -102,49 +114,24 @@ public class DateUtil {
: FastDateFormat.getInstance(pattern, DateUtil.DEFAULT_TIME_ZONE);
}
- private static ThreadLocal<Format> dateFormat =
- new ThreadLocal < Format > () {
- @Override protected Format initialValue() {
- return getDateParser(DEFAULT_DATE_FORMAT);
- }
- };
-
- public static Date parseDate(String dateValue) {
+ private static DateTime parseDateTime(String dateTimeValue) {
try {
- return (Date)dateFormat.get().parseObject(dateValue);
- } catch (ParseException e) {
+ return DATE_TIME_PARSER.parseDateTime(dateTimeValue);
+ } catch (IllegalArgumentException e) {
throw new IllegalDataException(e);
}
}
- private static ThreadLocal<Format> timeFormat =
- new ThreadLocal < Format > () {
- @Override protected Format initialValue() {
- return getTimeParser(DEFAULT_DATE_FORMAT);
- }
- };
+ public static Date parseDate(String dateValue) {
+ return new Date(parseDateTime(dateValue).getMillis());
+ }
public static Time parseTime(String timeValue) {
- try {
- return (Time)timeFormat.get().parseObject(timeValue);
- } catch (ParseException e) {
- throw new IllegalDataException(e);
- }
+ return new Time(parseDateTime(timeValue).getMillis());
}
- private static ThreadLocal<Format> timestampFormat =
- new ThreadLocal < Format > () {
- @Override protected Format initialValue() {
- return getTimestampParser(DEFAULT_DATE_FORMAT);
- }
- };
-
- public static Timestamp parseTimestamp(String timeValue) {
- try {
- return (Timestamp)timestampFormat.get().parseObject(timeValue);
- } catch (ParseException e) {
- throw new IllegalDataException(e);
- }
+ public static Timestamp parseTimestamp(String timestampValue) {
+ return new Timestamp(parseDateTime(timestampValue).getMillis());
}
/**
http://git-wip-us.apache.org/repos/asf/phoenix/blob/ddeacbf7/phoenix-core/src/test/java/org/apache/phoenix/util/DateUtilTest.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/util/DateUtilTest.java b/phoenix-core/src/test/java/org/apache/phoenix/util/DateUtilTest.java
index 36acf70..e5d4dfa 100644
--- a/phoenix-core/src/test/java/org/apache/phoenix/util/DateUtilTest.java
+++ b/phoenix-core/src/test/java/org/apache/phoenix/util/DateUtilTest.java
@@ -23,11 +23,13 @@ import java.sql.Timestamp;
import java.text.ParseException;
import java.util.TimeZone;
+import org.apache.phoenix.schema.IllegalDataException;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
/**
* Test class for {@link DateUtil}
@@ -127,4 +129,44 @@ public class DateUtilTest {
"HH:mm:ss", TimeZone.getDefault()).parseObject("00:00:00");
assertEquals(Time.valueOf("00:00:00"), time);
}
+
+ @Test
+ public void testParseDate() {
+ assertEquals(10000L, DateUtil.parseDate("1970-01-01 00:00:10").getTime());
+ }
+
+ @Test
+ public void testParseDate_PureDate() {
+ assertEquals(0L, DateUtil.parseDate("1970-01-01").getTime());
+ }
+
+ @Test(expected = IllegalDataException.class)
+ public void testParseDate_InvalidDate() {
+ DateUtil.parseDate("not-a-date");
+ }
+
+ @Test
+ public void testParseTime() {
+ assertEquals(10000L, DateUtil.parseTime("1970-01-01 00:00:10").getTime());
+ }
+
+ @Test(expected=IllegalDataException.class)
+ public void testParseTime_InvalidTime() {
+ DateUtil.parseDate("not-a-time");
+ }
+
+ @Test
+ public void testParseTimestamp() {
+ assertEquals(10000L, DateUtil.parseTimestamp("1970-01-01 00:00:10").getTime());
+ }
+
+ @Test
+ public void testParseTimestamp_WithMillis() {
+ assertEquals(10123L, DateUtil.parseTimestamp("1970-01-01 00:00:10.123").getTime());
+ }
+
+ @Test(expected=IllegalDataException.class)
+ public void testParseTimestamp_InvalidTimestamp() {
+ DateUtil.parseTimestamp("not-a-timestamp");
+ }
}