This is an automated email from the ASF dual-hosted git repository. pboado pushed a commit to branch 5.x-cdh6 in repository https://gitbox.apache.org/repos/asf/phoenix.git
commit 4cb9269404d6ccbee440380d6e58db783b19b552 Author: Xinyi Yan <x...@salesforce.com> AuthorDate: Tue Mar 5 06:24:36 2019 +0000 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 {