PHOENIX-2803 Initializing ToCharFunction with the List<Expression> constructor fails
Project: http://git-wip-us.apache.org/repos/asf/phoenix/repo Commit: http://git-wip-us.apache.org/repos/asf/phoenix/commit/b9880503 Tree: http://git-wip-us.apache.org/repos/asf/phoenix/tree/b9880503 Diff: http://git-wip-us.apache.org/repos/asf/phoenix/diff/b9880503 Branch: refs/heads/calcite Commit: b98805039516bfa706f1fa78ed0850d802df5dc8 Parents: d07fed5 Author: Thomas D'Silva <tdsi...@salesforce.com> Authored: Mon Mar 28 12:01:12 2016 -0700 Committer: Thomas D'Silva <tdsi...@salesforce.com> Committed: Mon Mar 28 14:23:51 2016 -0700 ---------------------------------------------------------------------- .../apache/phoenix/end2end/ToCharFunctionIT.java | 15 +++++++++++++++ .../apache/phoenix/end2end/ToDateFunctionIT.java | 15 +++++++++++++++ .../expression/function/ToCharFunction.java | 13 +++++++++---- .../expression/function/ToDateFunction.java | 17 +++++++++++------ .../expression/function/ToNumberFunction.java | 14 ++++++++++---- .../expression/function/ToTimeFunction.java | 13 +++++++++---- .../expression/function/ToTimestampFunction.java | 13 +++++++++---- .../function/BuiltinFunctionConstructorTest.java | 11 ++++++++--- 8 files changed, 86 insertions(+), 25 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/phoenix/blob/b9880503/phoenix-core/src/it/java/org/apache/phoenix/end2end/ToCharFunctionIT.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/ToCharFunctionIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/ToCharFunctionIT.java index 52b5207..1cccf07 100644 --- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/ToCharFunctionIT.java +++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/ToCharFunctionIT.java @@ -28,6 +28,7 @@ import java.sql.Date; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; +import java.sql.SQLException; import java.sql.Time; import java.sql.Timestamp; import java.text.DateFormat; @@ -240,4 +241,18 @@ public class ToCharFunctionIT extends BaseClientManagedTimeIT { result.setTimeZone(TimeZone.getTimeZone("GMT")); return result; } + + @Test + public void testToCharWithCloneMethod() throws SQLException { + Connection conn = DriverManager.getConnection(getUrl()); + String ddl = "create table t (k varchar primary key, v integer[])"; + conn.createStatement().execute(ddl); + conn.createStatement().execute("UPSERT INTO T VALUES('x',ARRAY[1234])"); + conn.commit(); + + ResultSet rs = conn.createStatement().executeQuery("select to_char(v[1],'000') from t"); + assertTrue(rs.next()); + assertEquals("Unexpected value for date ", String.valueOf(1234), rs.getString(1)); + assertFalse(rs.next()); + } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/phoenix/blob/b9880503/phoenix-core/src/it/java/org/apache/phoenix/end2end/ToDateFunctionIT.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/ToDateFunctionIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/ToDateFunctionIT.java index dbe47ca..acb29df 100644 --- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/ToDateFunctionIT.java +++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/ToDateFunctionIT.java @@ -251,4 +251,19 @@ public class ToDateFunctionIT extends BaseHBaseManagedTimeIT { assertEquals("Did not get value that was inserted!!", dateString2, obtainedString); assertFalse("No more rows expected!!", rs.next()); } + + @Test + public void testToDateWithCloneMethod() throws SQLException { + Connection conn = DriverManager.getConnection(getUrl()); + String ddl = "create table t (k varchar primary key, v varchar[])"; + conn.createStatement().execute(ddl); + String dateStr = "2100-01-01"; + conn.createStatement().execute("UPSERT INTO T VALUES('x',ARRAY['"+dateStr+"'])"); + conn.commit(); + ResultSet rs = conn.createStatement().executeQuery("select to_date(v[1], 'yyyy-MM-dd', 'local') from t"); + + assertTrue(rs.next()); + assertEquals("Unexpected value for date ", Date.valueOf(dateStr), rs.getDate(1)); + assertFalse(rs.next()); + } } http://git-wip-us.apache.org/repos/asf/phoenix/blob/b9880503/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ToCharFunction.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ToCharFunction.java b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ToCharFunction.java index a14a0cb..d284e25 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ToCharFunction.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ToCharFunction.java @@ -57,10 +57,6 @@ public class ToCharFunction extends ScalarFunction { public ToCharFunction() { } - public ToCharFunction(List<Expression> children) throws SQLException { - this(children, null, null, null); - } - public ToCharFunction(List<Expression> children, FunctionArgumentType type, String formatString, Format formatter) throws SQLException { super(children.subList(0, 1)); Preconditions.checkNotNull(formatString); @@ -72,6 +68,15 @@ public class ToCharFunction extends ScalarFunction { } @Override + public ToCharFunction clone(List<Expression> children) { + try { + return new ToCharFunction(children, type, formatString, formatter); + } catch (Exception e) { + throw new RuntimeException(e); // Impossible, since it was originally constructed this way + } + } + + @Override public int hashCode() { final int prime = 31; int result = 1; http://git-wip-us.apache.org/repos/asf/phoenix/blob/b9880503/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 f41d959..17f6847 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 @@ -53,21 +53,26 @@ import org.apache.phoenix.util.DateUtil; public class ToDateFunction extends ScalarFunction { public static final String NAME = "TO_DATE"; private DateUtil.DateTimeParser dateParser; - private String dateFormat; - private String timeZoneId; + protected String dateFormat; + protected String timeZoneId; public ToDateFunction() { } - public ToDateFunction(List<Expression> children) throws SQLException { - this(children, null, null); - } - public ToDateFunction(List<Expression> children, String dateFormat, String timeZoneId) throws SQLException { super(children); init(dateFormat, timeZoneId); } + @Override + public ToDateFunction clone(List<Expression> children) { + try { + return new ToDateFunction(children, dateFormat, timeZoneId); + } catch (Exception e) { + throw new RuntimeException(e); // Impossible, since it was originally constructed this way + } + } + private void init(String dateFormat, String timeZoneId) { this.dateFormat = dateFormat; this.dateParser = DateUtil.getDateTimeParser(dateFormat, getDataType(), timeZoneId); http://git-wip-us.apache.org/repos/asf/phoenix/blob/b9880503/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ToNumberFunction.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ToNumberFunction.java b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ToNumberFunction.java index e7659a1..c43062f 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ToNumberFunction.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ToNumberFunction.java @@ -30,6 +30,7 @@ import org.apache.hadoop.hbase.io.ImmutableBytesWritable; import org.apache.hadoop.io.WritableUtils; import com.google.common.base.Preconditions; + import org.apache.phoenix.expression.Expression; import org.apache.phoenix.parse.FunctionParseNode.Argument; import org.apache.phoenix.parse.FunctionParseNode.BuiltInFunction; @@ -60,10 +61,6 @@ public class ToNumberFunction extends ScalarFunction { public ToNumberFunction() {} - public ToNumberFunction(List<Expression> children) throws SQLException { - this(children, null, null, null); - } - public ToNumberFunction(List<Expression> children, FunctionArgumentType type, String formatString, Format formatter) throws SQLException { super(children.subList(0, 1)); Preconditions.checkNotNull(type); @@ -71,6 +68,15 @@ public class ToNumberFunction extends ScalarFunction { this.formatString = formatString; this.format = formatter; } + + @Override + public ToNumberFunction clone(List<Expression> children) { + try { + return new ToNumberFunction(children, type, formatString, format); + } catch (Exception e) { + throw new RuntimeException(e); // Impossible, since it was originally constructed this way + } + } @Override public boolean evaluate(Tuple tuple, ImmutableBytesWritable ptr) { http://git-wip-us.apache.org/repos/asf/phoenix/blob/b9880503/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ToTimeFunction.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ToTimeFunction.java b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ToTimeFunction.java index 2fa0553..588cb92 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ToTimeFunction.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ToTimeFunction.java @@ -47,13 +47,18 @@ public class ToTimeFunction extends ToDateFunction { public ToTimeFunction() { } - public ToTimeFunction(List<Expression> children) throws SQLException { - this(children, null, null); - } - public ToTimeFunction(List<Expression> children, String dateFormat, String timeZoneId) throws SQLException { super(children, dateFormat, timeZoneId); } + + @Override + public ToTimeFunction clone(List<Expression> children) { + try { + return new ToTimeFunction(children, dateFormat, timeZoneId); + } catch (Exception e) { + throw new RuntimeException(e); // Impossible, since it was originally constructed this way + } + } @Override public PDataType getDataType() { http://git-wip-us.apache.org/repos/asf/phoenix/blob/b9880503/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ToTimestampFunction.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ToTimestampFunction.java b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ToTimestampFunction.java index 5a4828f..6c14595 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ToTimestampFunction.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ToTimestampFunction.java @@ -47,13 +47,18 @@ public class ToTimestampFunction extends ToDateFunction { public ToTimestampFunction() { } - public ToTimestampFunction(List<Expression> children) throws SQLException { - this(children, null, null); - } - public ToTimestampFunction(List<Expression> children, String dateFormat, String timeZoneId) throws SQLException { super(children, dateFormat, timeZoneId); } + + @Override + public ToTimestampFunction clone(List<Expression> children) { + try { + return new ToTimestampFunction(children, dateFormat, timeZoneId); + } catch (Exception e) { + throw new RuntimeException(e); // Impossible, since it was originally constructed this way + } + } @Override public PDataType getDataType() { http://git-wip-us.apache.org/repos/asf/phoenix/blob/b9880503/phoenix-core/src/test/java/org/apache/phoenix/expression/function/BuiltinFunctionConstructorTest.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/test/java/org/apache/phoenix/expression/function/BuiltinFunctionConstructorTest.java b/phoenix-core/src/test/java/org/apache/phoenix/expression/function/BuiltinFunctionConstructorTest.java index 5258283..69f39fb 100644 --- a/phoenix-core/src/test/java/org/apache/phoenix/expression/function/BuiltinFunctionConstructorTest.java +++ b/phoenix-core/src/test/java/org/apache/phoenix/expression/function/BuiltinFunctionConstructorTest.java @@ -18,6 +18,7 @@ package org.apache.phoenix.expression.function; import java.lang.reflect.Constructor; +import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; @@ -35,9 +36,13 @@ public class BuiltinFunctionConstructorTest { for(int i = 0; i < types.length; i++) { try { if((ScalarFunction.class.isAssignableFrom(types[i].getExpressionClass())) && (types[i].getExpressionClass() != UDFExpression.class)) { - Constructor cons = types[i].getExpressionClass().getDeclaredConstructor(List.class); - cons.setAccessible(true); - cons.newInstance(children); + Method cloneMethod = types[i].getExpressionClass().getMethod("clone", List.class); + // ScalarFunctions that implement clone(List<Expression>) don't need to implement a constructor that takes a List<Expression> + if (cloneMethod==null) { + Constructor cons = types[i].getExpressionClass().getDeclaredConstructor(List.class); + cons.setAccessible(true); + cons.newInstance(children); + } } } catch (NoSuchMethodException e) { throw new RuntimeException(e);