You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@phoenix.apache.org by el...@apache.org on 2018/07/31 20:59:55 UTC

[4/4] phoenix git commit: PHOENIX-4822 Ensure the provided timezone is used client-side (Jaanai Zhang)

PHOENIX-4822 Ensure the provided timezone is used client-side (Jaanai Zhang)


Project: http://git-wip-us.apache.org/repos/asf/phoenix/repo
Commit: http://git-wip-us.apache.org/repos/asf/phoenix/commit/81799428
Tree: http://git-wip-us.apache.org/repos/asf/phoenix/tree/81799428
Diff: http://git-wip-us.apache.org/repos/asf/phoenix/diff/81799428

Branch: refs/heads/4.x-HBase-1.2
Commit: 8179942827fa7bd759f26a77ebc664308ba378cb
Parents: 8e2e99d
Author: Josh Elser <el...@apache.org>
Authored: Tue Jul 31 15:53:11 2018 -0400
Committer: Josh Elser <el...@apache.org>
Committed: Tue Jul 31 16:37:58 2018 -0400

----------------------------------------------------------------------
 .../org/apache/phoenix/end2end/DateTimeIT.java  | 77 ++++++++++++++++++++
 .../phoenix/compile/StatementContext.java       | 11 +--
 .../apache/phoenix/jdbc/PhoenixConnection.java  |  8 +-
 .../java/org/apache/phoenix/util/DateUtil.java  | 22 +++---
 4 files changed, 101 insertions(+), 17 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/phoenix/blob/81799428/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 c976114..cc7c7a7 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
@@ -54,12 +54,19 @@ import java.text.Format;
 import java.util.Calendar;
 import java.util.GregorianCalendar;
 import java.util.Properties;
+import java.util.TimeZone;
 
+import org.apache.commons.lang.time.FastDateFormat;
 import org.apache.hadoop.hbase.filter.CompareFilter.CompareOp;
 import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
 import org.apache.hadoop.hbase.util.Bytes;
+import org.apache.phoenix.compile.StatementContext;
+import org.apache.phoenix.jdbc.PhoenixConnection;
+import org.apache.phoenix.jdbc.PhoenixStatement;
 import org.apache.phoenix.query.QueryConstants;
+import org.apache.phoenix.schema.types.PDataType;
 import org.apache.phoenix.schema.types.PDate;
+import org.apache.phoenix.schema.types.PTime;
 import org.apache.phoenix.schema.types.PTimestamp;
 import org.apache.phoenix.util.ByteUtil;
 import org.apache.phoenix.util.DateUtil;
@@ -1880,4 +1887,74 @@ public class DateTimeIT extends ParallelStatsDisabledIT {
             conn.close();
         }
     }
+
+    @Test
+    public void testDateFormatTimeZone()throws Exception {
+        String[] timeZoneIDs = {DateUtil.DEFAULT_TIME_ZONE_ID, "Asia/Yerevan", "Australia/Adelaide", "Asia/Tokyo"};
+        for (String timeZoneID : timeZoneIDs) {
+            testDateFormatTimeZone(timeZoneID);
+        }
+    }
+
+    public void testDateFormatTimeZone(String timeZoneId) throws Exception {
+        Properties props = new Properties();
+        props.setProperty("phoenix.query.dateFormatTimeZone", timeZoneId);
+        Connection conn1 = DriverManager.getConnection(getUrl(), props);
+
+        String tableName = generateUniqueName();
+        String ddl = "CREATE TABLE IF NOT EXISTS " + tableName +
+                " (k1 INTEGER PRIMARY KEY," +
+                " v_date DATE," +
+                " v_time TIME," +
+                " v_timestamp TIMESTAMP)";
+        try {
+            conn1.createStatement().execute(ddl);
+
+            PhoenixConnection pConn = conn1.unwrap(PhoenixConnection.class);
+            verifyTimeZoneIDWithConn(pConn, PDate.INSTANCE, timeZoneId);
+            verifyTimeZoneIDWithConn(pConn, PTime.INSTANCE, timeZoneId);
+            verifyTimeZoneIDWithConn(pConn, PTimestamp.INSTANCE, timeZoneId);
+
+            Calendar cal = Calendar.getInstance(TimeZone.getTimeZone(timeZoneId));
+            cal.setTime(date);
+            String dateStr = DateUtil.getDateFormatter(DateUtil.DEFAULT_MS_DATE_FORMAT).format(date);
+
+            String dml = "UPSERT INTO " + tableName + " VALUES (" +
+                    "1," +
+                    "'" + dateStr + "'," +
+                    "'" + dateStr + "'," +
+                    "'" + dateStr + "'" +
+                    ")";
+            conn1.createStatement().execute(dml);
+            conn1.commit();
+
+            PhoenixStatement stmt = conn1.createStatement().unwrap(PhoenixStatement.class);
+            ResultSet rs = stmt.executeQuery("SELECT v_date, v_time, v_timestamp FROM " + tableName);
+
+            assertTrue(rs.next());
+            assertEquals(rs.getDate(1).toString(), new Date(cal.getTimeInMillis()).toString());
+            assertEquals(rs.getTime(2).toString(), new Time(cal.getTimeInMillis()).toString());
+            assertEquals(rs.getTimestamp(3).getTime(), cal.getTimeInMillis());
+            assertFalse(rs.next());
+
+            StatementContext stmtContext = stmt.getQueryPlan().getContext();
+            verifyTimeZoneIDWithFormatter(stmtContext.getDateFormatter(), timeZoneId);
+            verifyTimeZoneIDWithFormatter(stmtContext.getTimeFormatter(), timeZoneId);
+            verifyTimeZoneIDWithFormatter(stmtContext.getTimestampFormatter(), timeZoneId);
+
+            stmt.close();
+        } finally {
+            conn1.close();
+        }
+    }
+
+    private void verifyTimeZoneIDWithConn(PhoenixConnection conn, PDataType dataType, String timeZoneId) {
+        Format formatter = conn.getFormatter(dataType);
+        verifyTimeZoneIDWithFormatter(formatter, timeZoneId);
+    }
+
+    private void verifyTimeZoneIDWithFormatter(Format formatter, String timeZoneId) {
+        assertTrue(formatter instanceof FastDateFormat);
+        assertEquals(((FastDateFormat)formatter).getTimeZone().getID(), timeZoneId);
+    }
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/81799428/phoenix-core/src/main/java/org/apache/phoenix/compile/StatementContext.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/StatementContext.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/StatementContext.java
index fe60bb9..eb195c2 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/StatementContext.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/StatementContext.java
@@ -120,14 +120,15 @@ public class StatementContext {
         this.expressions = new ExpressionManager();
         PhoenixConnection connection = statement.getConnection();
         ReadOnlyProps props = connection.getQueryServices().getProps();
+        String timeZoneID = props.get(QueryServices.DATE_FORMAT_TIMEZONE_ATTRIB,
+                DateUtil.DEFAULT_TIME_ZONE_ID);
         this.dateFormat = props.get(QueryServices.DATE_FORMAT_ATTRIB, DateUtil.DEFAULT_DATE_FORMAT);
-        this.dateFormatter = DateUtil.getDateFormatter(dateFormat);
+        this.dateFormatter = DateUtil.getDateFormatter(dateFormat, timeZoneID);
         this.timeFormat = props.get(QueryServices.TIME_FORMAT_ATTRIB, DateUtil.DEFAULT_TIME_FORMAT);
-        this.timeFormatter = DateUtil.getTimeFormatter(timeFormat);
+        this.timeFormatter = DateUtil.getTimeFormatter(timeFormat, timeZoneID);
         this.timestampFormat = props.get(QueryServices.TIMESTAMP_FORMAT_ATTRIB, DateUtil.DEFAULT_TIMESTAMP_FORMAT);
-        this.timestampFormatter = DateUtil.getTimestampFormatter(timestampFormat);
-        this.dateFormatTimeZone = DateUtil.getTimeZone(props.get(QueryServices.DATE_FORMAT_TIMEZONE_ATTRIB,
-                DateUtil.DEFAULT_TIME_ZONE_ID));
+        this.timestampFormatter = DateUtil.getTimestampFormatter(timestampFormat, timeZoneID);
+        this.dateFormatTimeZone = DateUtil.getTimeZone(timeZoneID);
         this.numberFormat = props.get(QueryServices.NUMBER_FORMAT_ATTRIB, NumberUtil.DEFAULT_NUMBER_FORMAT);
         this.tempPtr = new ImmutableBytesWritable();
         this.currentTable = resolver != null && !resolver.getTables().isEmpty() ? resolver.getTables().get(0) : null;

http://git-wip-us.apache.org/repos/asf/phoenix/blob/81799428/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixConnection.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixConnection.java b/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixConnection.java
index 3d9b261..6da579f 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixConnection.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixConnection.java
@@ -327,9 +327,11 @@ public class PhoenixConnection implements Connection, MetaDataMutated, SQLClosea
         int maxSizeBytes = this.services.getProps().getInt(
                 QueryServices.MAX_MUTATION_SIZE_BYTES_ATTRIB,
                 QueryServicesOptions.DEFAULT_MAX_MUTATION_SIZE_BYTES);
-        Format dateFormat = DateUtil.getDateFormatter(datePattern);
-        Format timeFormat = DateUtil.getDateFormatter(timePattern);
-        Format timestampFormat = DateUtil.getDateFormatter(timestampPattern);
+        String timeZoneID = this.services.getProps().get(QueryServices.DATE_FORMAT_TIMEZONE_ATTRIB,
+                DateUtil.DEFAULT_TIME_ZONE_ID);
+        Format dateFormat = DateUtil.getDateFormatter(datePattern, timeZoneID);
+        Format timeFormat = DateUtil.getDateFormatter(timePattern, timeZoneID);
+        Format timestampFormat = DateUtil.getDateFormatter(timestampPattern, timeZoneID);
         formatters.put(PDate.INSTANCE, dateFormat);
         formatters.put(PTime.INSTANCE, timeFormat);
         formatters.put(PTimestamp.INSTANCE, timestampFormat);

http://git-wip-us.apache.org/repos/asf/phoenix/blob/81799428/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 9e37eca..f67f152 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
@@ -97,7 +97,7 @@ public class DateUtil {
     
     public static TimeZone getTimeZone(String timeZoneId) {
         TimeZone parserTimeZone;
-        if (timeZoneId == null) {
+        if (timeZoneId == null || timeZoneId.equals(DateUtil.DEFAULT_TIME_ZONE_ID)) {
             parserTimeZone = DateUtil.DEFAULT_TIME_ZONE;
         } else if (LOCAL_TIME_ZONE_ID.equalsIgnoreCase(timeZoneId)) {
             parserTimeZone = TimeZone.getDefault();
@@ -164,21 +164,25 @@ public class DateUtil {
     }
 
     public static Format getDateFormatter(String pattern) {
-        return DateUtil.DEFAULT_DATE_FORMAT.equals(pattern)
+        return getDateFormatter(pattern, DateUtil.DEFAULT_TIME_ZONE_ID);
+    }
+
+    public static Format getDateFormatter(String pattern, String timeZoneID) {
+        return DateUtil.DEFAULT_DATE_FORMAT.equals(pattern) && DateUtil.DEFAULT_TIME_ZONE_ID.equals(timeZoneID)
                 ? DateUtil.DEFAULT_DATE_FORMATTER
-                : FastDateFormat.getInstance(pattern, DateUtil.DEFAULT_TIME_ZONE);
+                : FastDateFormat.getInstance(pattern, getTimeZone(timeZoneID));
     }
 
-    public static Format getTimeFormatter(String pattern) {
-        return DateUtil.DEFAULT_TIME_FORMAT.equals(pattern)
+    public static Format getTimeFormatter(String pattern, String timeZoneID) {
+        return DateUtil.DEFAULT_TIME_FORMAT.equals(pattern) && DateUtil.DEFAULT_TIME_ZONE_ID.equals(timeZoneID)
                 ? DateUtil.DEFAULT_TIME_FORMATTER
-                : FastDateFormat.getInstance(pattern, DateUtil.DEFAULT_TIME_ZONE);
+                : FastDateFormat.getInstance(pattern, getTimeZone(timeZoneID));
     }
 
-    public static Format getTimestampFormatter(String pattern) {
-        return DateUtil.DEFAULT_TIMESTAMP_FORMAT.equals(pattern)
+    public static Format getTimestampFormatter(String pattern, String timeZoneID) {
+        return DateUtil.DEFAULT_TIMESTAMP_FORMAT.equals(pattern) && DateUtil.DEFAULT_TIME_ZONE_ID.equals(timeZoneID)
                 ? DateUtil.DEFAULT_TIMESTAMP_FORMATTER
-                : FastDateFormat.getInstance(pattern, DateUtil.DEFAULT_TIME_ZONE);
+                : FastDateFormat.getInstance(pattern, getTimeZone(timeZoneID));
     }
 
     private static long parseDateTime(String dateTimeValue) {