You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@phoenix.apache.org by vi...@apache.org on 2019/03/06 19:33:05 UTC

[phoenix] branch master updated: PHOENIX-4929 IndexOutOfBoundsException when casting timestamp to date

This is an automated email from the ASF dual-hosted git repository.

vincentpoon pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/phoenix.git


The following commit(s) were added to refs/heads/master by this push:
     new 7dad115  PHOENIX-4929 IndexOutOfBoundsException when casting timestamp to date
7dad115 is described below

commit 7dad115b1dcf7581905575cb7d858dc645a61e83
Author: Xinyi Yan <xy...@salesforce.com>
AuthorDate: Mon Mar 4 22:24:36 2019 -0800

    PHOENIX-4929 IndexOutOfBoundsException when casting timestamp to date
---
 .../org/apache/phoenix/end2end/DateTimeIT.java     | 28 ++++++++++++++++++++++
 .../apache/phoenix/compile/ExpressionCompiler.java | 13 ++++++----
 .../apache/phoenix/compile/QueryCompilerTest.java  |  7 ++++++
 3 files changed, 44 insertions(+), 4 deletions(-)

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 eecc540..df94a70 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
@@ -51,6 +51,7 @@ import java.sql.Time;
 import java.sql.Timestamp;
 import java.sql.Types;
 import java.text.Format;
+import java.time.LocalDate;
 import java.util.Calendar;
 import java.util.GregorianCalendar;
 import java.util.Properties;
@@ -1823,6 +1824,33 @@ public class DateTimeIT extends ParallelStatsDisabledIT {
         }
     }
 
+    @Test
+    public void testCastTimeStampToDate() throws Exception {
+        String tablename = generateUniqueName();
+        String ddl = "CREATE TABLE IF NOT EXISTS " + tablename +
+                " (PK INTEGER PRIMARY KEY, A_TIMESTAMP TIMESTAMP)";
+        Properties props = new Properties();
+        props.setProperty("phoenix.query.dateFormatTimeZone", TimeZone.getDefault().toString());
+        Connection conn = DriverManager.getConnection(getUrl(), props);
+        conn.createStatement().execute(ddl);
+
+        String localTime = LocalDate.now().toString();
+        conn.createStatement().execute("UPSERT INTO " + tablename +
+                " VALUES(1,TO_TIMESTAMP('"+ localTime + "'))");
+
+        conn.setAutoCommit(true);
+        try {
+            PreparedStatement statement =
+                    conn.prepareStatement("SELECT CAST(A_TIMESTAMP AS DATE) as A_DATE FROM " + tablename);
+
+            ResultSet rs = statement.executeQuery();
+            assertTrue (rs.next());
+            assertTrue (rs.getString(1).contains(localTime));
+            assertFalse (rs.next());
+        } finally {
+            conn.close();
+        }
+    }
 
     @Test
     public void testTimestamp() throws Exception {
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/ExpressionCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/ExpressionCompiler.java
index 077e1af..980c1b9 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/ExpressionCompiler.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/ExpressionCompiler.java
@@ -586,11 +586,16 @@ public class ExpressionCompiler extends UnsupportedAllParseNodeVisitor<Expressio
         Expression firstChildExpr = expressions.get(0);
         if(fromDataType == targetDataType) {
             return firstChildExpr;
-        } else if((fromDataType == PDecimal.INSTANCE || fromDataType == PTimestamp.INSTANCE || fromDataType == PUnsignedTimestamp.INSTANCE) && targetDataType.isCoercibleTo(
-          PLong.INSTANCE)) {
+        } else if ((fromDataType == PDecimal.INSTANCE || fromDataType == PTimestamp.INSTANCE ||
+                fromDataType == PUnsignedTimestamp.INSTANCE) && targetDataType.isCoercibleTo(
+                PLong.INSTANCE)) {
             return RoundDecimalExpression.create(expressions);
-        } else if((fromDataType == PDecimal.INSTANCE || fromDataType == PTimestamp.INSTANCE || fromDataType == PUnsignedTimestamp.INSTANCE) && targetDataType.isCoercibleTo(
-          PDate.INSTANCE)) {
+        } else if (expressions.size() == 1 && fromDataType == PTimestamp.INSTANCE  &&
+                targetDataType.isCoercibleTo(PDate.INSTANCE)) {
+            return firstChildExpr;
+        } else if((fromDataType == PDecimal.INSTANCE || fromDataType == PTimestamp.INSTANCE ||
+                fromDataType == PUnsignedTimestamp.INSTANCE) && targetDataType.isCoercibleTo(
+                        PDate.INSTANCE)) {
             return RoundTimestampExpression.create(expressions);
         } else if(fromDataType.isCastableTo(targetDataType)) {
             return firstChildExpr;
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/compile/QueryCompilerTest.java b/phoenix-core/src/test/java/org/apache/phoenix/compile/QueryCompilerTest.java
index 2c438a6..ab804e5 100644
--- a/phoenix-core/src/test/java/org/apache/phoenix/compile/QueryCompilerTest.java
+++ b/phoenix-core/src/test/java/org/apache/phoenix/compile/QueryCompilerTest.java
@@ -1111,6 +1111,13 @@ public class QueryCompilerTest extends BaseConnectionlessQueryTest {
         List<Object> binds = Collections.emptyList();
         compileQuery(query, binds);
     }
+
+    @Test
+    public void testCastingTimestampToDateInSelect() throws Exception {
+        String query = "SELECT CAST (a_timestamp AS DATE) FROM aTable";
+        List<Object> binds = Collections.emptyList();
+        compileQuery(query, binds);
+    }
     
     @Test
     public void testCastingStringToDecimalInSelect() throws Exception {