Repository: phoenix
Updated Branches:
  refs/heads/4.x-HBase-1.1 5998f2aeb -> 3760be37c


PHOENIX-3355 Register Phoenix built-in functions as Calcite functions


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

Branch: refs/heads/4.x-HBase-1.1
Commit: 3760be37c354534f8538e0ba31a410136f32a82d
Parents: 5998f2a
Author: Eric Lomore <eric.lom...@gmail.com>
Authored: Wed Dec 21 17:19:53 2016 -0800
Committer: maryannxue <maryann....@gmail.com>
Committed: Wed Dec 21 17:19:53 2016 -0800

----------------------------------------------------------------------
 .../org/apache/phoenix/end2end/DateTimeIT.java  | 48 ++++++++++----------
 .../phoenix/end2end/DefaultColumnValueIT.java   |  6 +--
 .../phoenix/end2end/ToDateFunctionIT.java       |  2 +-
 .../phoenix/end2end/index/LocalIndexIT.java     |  6 +--
 .../ByteBasedRegexpReplaceFunction.java         | 11 +++++
 .../function/ByteBasedRegexpSplitFunction.java  | 10 ++++
 .../function/ByteBasedRegexpSubstrFunction.java | 16 +++++++
 .../expression/function/CeilDateExpression.java | 14 ++++++
 .../function/CeilDecimalExpression.java         | 13 ++++++
 .../expression/function/CeilFunction.java       | 10 +++-
 .../function/CeilTimestampExpression.java       | 13 ++++++
 .../function/CurrentDateFunction.java           |  9 ++++
 .../function/CurrentTimeFunction.java           |  9 ++++
 .../expression/function/FirstValueFunction.java |  4 ++
 .../function/FloorDateExpression.java           | 13 ++++++
 .../function/FloorDecimalExpression.java        | 13 ++++++
 .../expression/function/FloorFunction.java      |  5 +-
 .../expression/function/LastValueFunction.java  |  4 ++
 .../function/MaxAggregateFunction.java          |  4 ++
 .../function/MinAggregateFunction.java          |  4 ++
 .../expression/function/NowFunction.java        |  5 +-
 .../expression/function/NthValueFunction.java   |  4 ++
 .../function/RegexpReplaceFunction.java         |  5 +-
 .../function/RegexpSplitFunction.java           |  4 +-
 .../function/RegexpSubstrFunction.java          |  5 +-
 .../function/RoundDateExpression.java           | 12 +++++
 .../function/RoundDecimalExpression.java        | 12 +++++
 .../expression/function/RoundFunction.java      |  5 +-
 .../function/RoundTimestampExpression.java      | 14 +++++-
 .../StringBasedRegexpReplaceFunction.java       | 12 +++++
 .../StringBasedRegexpSplitFunction.java         | 10 ++++
 .../StringBasedRegexpSubstrFunction.java        | 12 +++++
 .../expression/function/ToCharFunction.java     | 34 ++++++++++++++
 .../expression/function/ToDateFunction.java     | 14 ++++++
 .../expression/function/ToNumberFunction.java   | 34 ++++++++++++++
 .../expression/function/ToTimeFunction.java     |  6 +++
 .../function/ToTimestampFunction.java           |  5 ++
 .../expression/function/TruncFunction.java      |  5 +-
 .../apache/phoenix/parse/FunctionParseNode.java | 31 +++++++++++++
 .../apache/phoenix/parse/ParseNodeFactory.java  | 38 +++++++++++-----
 40 files changed, 429 insertions(+), 52 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/phoenix/blob/3760be37/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 ffcb472..74cc068 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
@@ -411,45 +411,45 @@ public class DateTimeIT extends ParallelStatsDisabledIT {
     @Test
     public void testYearFunctionDate() throws SQLException {
 
-        assertEquals(2008, callYearFunction("YEAR(TO_DATE('2008-01-01', 
'yyyy-MM-dd', 'local'))"));
+        assertEquals(2008, callYearFunction("\"YEAR\"(TO_DATE('2008-01-01', 
'yyyy-MM-dd', 'local'))"));
 
         assertEquals(2004,
-            callYearFunction("YEAR(TO_DATE('2004-12-13 10:13:18', 'yyyy-MM-dd 
hh:mm:ss'))"));
+            callYearFunction("\"YEAR\"(TO_DATE('2004-12-13 10:13:18', 
'yyyy-MM-dd hh:mm:ss'))"));
 
-        assertEquals(2015, 
callYearFunction("YEAR(TO_DATE('2015-01-27T16:17:57+00:00'))"));
+        assertEquals(2015, 
callYearFunction("\"YEAR\"(TO_DATE('2015-01-27T16:17:57+00:00'))"));
 
-        assertEquals(2005, callYearFunction("YEAR(TO_DATE('2005-12-13 
10:13:18'))"));
+        assertEquals(2005, callYearFunction("\"YEAR\"(TO_DATE('2005-12-13 
10:13:18'))"));
 
-        assertEquals(2006, callYearFunction("YEAR(TO_DATE('2006-12-13'))"));
+        assertEquals(2006, 
callYearFunction("\"YEAR\"(TO_DATE('2006-12-13'))"));
 
-        assertEquals(2015, callYearFunction("YEAR(TO_DATE('2015-W05'))"));
+        assertEquals(2015, callYearFunction("\"YEAR\"(TO_DATE('2015-W05'))"));
 
         assertEquals(
             2008,
-            callYearFunction("YEAR(TO_DATE('Sat, 3 Feb 2008 03:05:06 GMT', 
'EEE, d MMM yyyy HH:mm:ss z', 'UTC'))"));
+            callYearFunction("\"YEAR\"(TO_DATE('Sat, 3 Feb 2008 03:05:06 GMT', 
'EEE, d MMM yyyy HH:mm:ss z', 'UTC'))"));
     }
 
     @Test
     public void testYearFunctionTimestamp() throws SQLException {
 
-        assertEquals(2015, 
callYearFunction("YEAR(TO_TIMESTAMP('2015-01-27T16:17:57+00:00'))"));
+        assertEquals(2015, 
callYearFunction("\"YEAR\"(TO_TIMESTAMP('2015-01-27T16:17:57+00:00'))"));
 
-        assertEquals(2015, 
callYearFunction("YEAR(TO_TIMESTAMP('2015-01-27T16:17:57Z'))"));
+        assertEquals(2015, 
callYearFunction("\"YEAR\"(TO_TIMESTAMP('2015-01-27T16:17:57Z'))"));
 
-        assertEquals(2015, 
callYearFunction("YEAR(TO_TIMESTAMP('2015-W10-3'))"));
+        assertEquals(2015, 
callYearFunction("\"YEAR\"(TO_TIMESTAMP('2015-W10-3'))"));
 
-        assertEquals(2015, callYearFunction("YEAR(TO_TIMESTAMP('2015-W05'))"));
+        assertEquals(2015, 
callYearFunction("\"YEAR\"(TO_TIMESTAMP('2015-W05'))"));
 
-        assertEquals(2015, callYearFunction("YEAR(TO_TIMESTAMP('2015-063'))"));
+        assertEquals(2015, 
callYearFunction("\"YEAR\"(TO_TIMESTAMP('2015-063'))"));
 
-        assertEquals(2006, 
callYearFunction("YEAR(TO_TIMESTAMP('2006-12-13'))"));
+        assertEquals(2006, 
callYearFunction("\"YEAR\"(TO_TIMESTAMP('2006-12-13'))"));
 
         assertEquals(2004,
-            callYearFunction("YEAR(TO_TIMESTAMP('2004-12-13 10:13:18', 
'yyyy-MM-dd hh:mm:ss'))"));
+            callYearFunction("\"YEAR\"(TO_TIMESTAMP('2004-12-13 10:13:18', 
'yyyy-MM-dd hh:mm:ss'))"));
 
         assertEquals(
             2008,
-            callYearFunction("YEAR(TO_TIMESTAMP('Sat, 3 Feb 2008 03:05:06 
GMT', 'EEE, d MMM yyyy HH:mm:ss z', 'UTC'))"));
+            callYearFunction("\"YEAR\"(TO_TIMESTAMP('Sat, 3 Feb 2008 03:05:06 
GMT', 'EEE, d MMM yyyy HH:mm:ss z', 'UTC'))"));
     }
 
     @Test
@@ -470,8 +470,8 @@ public class DateTimeIT extends ParallelStatsDisabledIT {
         conn.createStatement().execute(dml);
         conn.commit();
 
-        ResultSet rs = conn.createStatement().executeQuery("SELECT k1, 
YEAR(timestamps), YEAR(times), Year(unsignedDates), YEAR(unsignedTimestamps), " 
+
-                "YEAR(unsignedTimes) FROM " + tableName + " where YEAR(dates) 
= 2004");
+        ResultSet rs = conn.createStatement().executeQuery("SELECT k1, 
\"YEAR\"(timestamps), \"YEAR\"(times), \"YEAR\"(unsignedDates), 
\"YEAR\"(unsignedTimestamps), " +
+                "\"YEAR\"(unsignedTimes) FROM " + tableName + " where 
\"YEAR\"(dates) = 2004");
         assertTrue(rs.next());
         assertEquals(1, rs.getInt(1));
         assertEquals(2006, rs.getInt(2));
@@ -500,8 +500,8 @@ public class DateTimeIT extends ParallelStatsDisabledIT {
         conn.createStatement().execute(dml);
         conn.commit();
 
-        ResultSet rs = conn.createStatement().executeQuery("SELECT k1, 
MONTH(timestamps), MONTH(times), MONTH(unsignedDates), 
MONTH(unsignedTimestamps), " +
-                "MONTH(unsignedTimes) FROM " + tableName + " where 
MONTH(dates) = 3");
+        ResultSet rs = conn.createStatement().executeQuery("SELECT k1, 
\"MONTH\"(timestamps), \"MONTH\"(times), \"MONTH\"(unsignedDates), 
\"MONTH\"(unsignedTimestamps), " +
+                "\"MONTH\"(unsignedTimes) FROM " + tableName + " where 
\"MONTH\"(dates) = 3");
         assertTrue(rs.next());
         assertEquals(1, rs.getInt(1));
         assertEquals(4, rs.getInt(2));
@@ -577,7 +577,7 @@ public class DateTimeIT extends ParallelStatsDisabledIT {
         conn.createStatement().execute(dml);
         conn.commit();
 
-        ResultSet rs = conn.createStatement().executeQuery("SELECT k1, 
WEEK(dates), WEEK(times) FROM " + tableName + " where WEEK(timestamps)=15");
+        ResultSet rs = conn.createStatement().executeQuery("SELECT k1, 
\"WEEK\"(dates), \"WEEK\"(times) FROM " + tableName + " where 
\"WEEK\"(timestamps)=15");
         assertTrue(rs.next());
         assertEquals(1, rs.getInt(1));
         assertEquals(2, rs.getInt(2));
@@ -602,7 +602,7 @@ public class DateTimeIT extends ParallelStatsDisabledIT {
         conn.createStatement().execute(dml);
         conn.commit();
 
-        ResultSet rs = conn.createStatement().executeQuery("SELECT k1, 
HOUR(dates), HOUR(times) FROM " + tableName + " where HOUR(timestamps)=15");
+        ResultSet rs = conn.createStatement().executeQuery("SELECT k1, 
\"HOUR\"(dates), \"HOUR\"(times) FROM " + tableName + " where 
\"HOUR\"(timestamps)=15");
         assertTrue(rs.next());
         assertEquals(1, rs.getInt(1));
         assertEquals(3, rs.getInt(2));
@@ -649,8 +649,8 @@ public class DateTimeIT extends ParallelStatsDisabledIT {
         conn.createStatement().execute(dml);
         conn.commit();
 
-        ResultSet rs = conn.createStatement().executeQuery("SELECT k1, 
MINUTE(dates), MINUTE(times), MINUTE(unsignedDates), 
MINUTE(unsignedTimestamps), " +
-                "MINUTE(unsignedTimes) FROM " + tableName + " where 
MINUTE(timestamps)=20");
+        ResultSet rs = conn.createStatement().executeQuery("SELECT k1, 
\"MINUTE\"(dates), \"MINUTE\"(times), \"MINUTE\"(unsignedDates), 
\"MINUTE\"(unsignedTimestamps), " +
+                "\"MINUTE\"(unsignedTimes) FROM " + tableName + " where 
\"MINUTE\"(timestamps)=20");
         assertTrue(rs.next());
         assertEquals(1, rs.getInt(1));
         assertEquals(10, rs.getInt(2));
@@ -835,7 +835,7 @@ public class DateTimeIT extends ParallelStatsDisabledIT {
     
     @Test
     public void testFunctionOnNullDate() throws Exception {
-        ResultSet rs = conn.createStatement().executeQuery("SELECT 
YEAR(a_date), entity_id from " + this.tableName + " WHERE entity_id = '" + 
ROW10 + "'");
+        ResultSet rs = conn.createStatement().executeQuery("SELECT 
\"YEAR\"(a_date), entity_id from " + this.tableName + " WHERE entity_id = '" + 
ROW10 + "'");
         assertNotNull(rs);
         assertTrue(rs.next());
         assertEquals(ROW10, rs.getString(2));

http://git-wip-us.apache.org/repos/asf/phoenix/blob/3760be37/phoenix-core/src/it/java/org/apache/phoenix/end2end/DefaultColumnValueIT.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/it/java/org/apache/phoenix/end2end/DefaultColumnValueIT.java 
b/phoenix-core/src/it/java/org/apache/phoenix/end2end/DefaultColumnValueIT.java
index 783dd75..62d79bc 100644
--- 
a/phoenix-core/src/it/java/org/apache/phoenix/end2end/DefaultColumnValueIT.java
+++ 
b/phoenix-core/src/it/java/org/apache/phoenix/end2end/DefaultColumnValueIT.java
@@ -586,7 +586,7 @@ public class DefaultColumnValueIT extends 
ParallelStatsDisabledIT {
                 + "c3 DECIMAL DEFAULT TO_NUMBER('$123.33', '\u00A4###.##'),"
                 + "c4 VARCHAR DEFAULT 'AB' || 'CD',"
                 + "c5 CHAR(5) DEFAULT 'E' || 'F',"
-                + "c6 INTEGER DEFAULT MONTH(TO_TIMESTAMP('2015-6-05'))"
+                + "c6 INTEGER DEFAULT \"MONTH\"(TO_TIMESTAMP('2015-6-05'))"
                 + ")";
 
         verifyDefaultExpression(sharedTable2, ddl);
@@ -602,7 +602,7 @@ public class DefaultColumnValueIT extends 
ParallelStatsDisabledIT {
                 + "c3 DECIMAL NOT NULL DEFAULT TO_NUMBER('$123.33', 
'\u00A4###.##'),"
                 + "c4 VARCHAR NOT NULL DEFAULT 'AB' || 'CD',"
                 + "c5 CHAR(5) NOT NULL DEFAULT 'E' || 'F',"
-                + "c6 INTEGER NOT NULL DEFAULT 
MONTH(TO_TIMESTAMP('2015-6-05')),"
+                + "c6 INTEGER NOT NULL DEFAULT 
\"MONTH\"(TO_TIMESTAMP('2015-6-05')),"
                 + "CONSTRAINT pk_key PRIMARY KEY (pk,c1,c2,c3,c4,c5,c6)"
                 + ")";
 
@@ -1048,7 +1048,7 @@ public class DefaultColumnValueIT extends 
ParallelStatsDisabledIT {
                 + "c3 DECIMAL DEFAULT TO_NUMBER('$123.33', '\u00A4###.##'),"
                 + "c4 VARCHAR DEFAULT 'AB' || 'CD',"
                 + "c5 CHAR(5) DEFAULT 'E' || 'F',"
-                + "c6 INTEGER DEFAULT MONTH(TO_TIMESTAMP('2015-6-05'))"
+                + "c6 INTEGER DEFAULT \"MONTH\"(TO_TIMESTAMP('2015-6-05'))"
                 + ")";
 
         Connection conn = DriverManager.getConnection(getUrl());

http://git-wip-us.apache.org/repos/asf/phoenix/blob/3760be37/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 6053ef5..fe86a22 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
@@ -48,7 +48,7 @@ public class ToDateFunctionIT extends ParallelStatsDisabledIT 
{
 
     private static java.util.Date callToDateFunction(Connection conn, String 
invocation) throws SQLException {
         Statement stmt = conn.createStatement();
-        ResultSet rs = stmt.executeQuery(String.format("SELECT %s FROM 
SYSTEM.CATALOG LIMIT 1", invocation));
+        ResultSet rs = stmt.executeQuery(String.format("SELECT %s FROM 
\"SYSTEM\".CATALOG LIMIT 1", invocation));
         assertTrue(rs.next());
         java.util.Date returnValue = (java.util.Date)rs.getObject(1);
         rs.close();

http://git-wip-us.apache.org/repos/asf/phoenix/blob/3760be37/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/LocalIndexIT.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/LocalIndexIT.java 
b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/LocalIndexIT.java
index 785a324..278f4cf 100644
--- 
a/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/LocalIndexIT.java
+++ 
b/phoenix-core/src/it/java/org/apache/phoenix/end2end/index/LocalIndexIT.java
@@ -89,16 +89,16 @@ public class LocalIndexIT extends BaseLocalIndexIT {
         conn1.createStatement().execute(createTable);
         conn1.createStatement().execute(
             "CREATE local INDEX IF NOT EXISTS " + indexName2 + " on " + 
tableName2
-                    + "(HOUR(user_time))");
+                    + "(\"HOUR\"(user_time))");
         conn1.createStatement().execute(
             "upsert into " + tableName2 + " values(TO_TIME('2005-10-01 
14:03:22.559'), 'foo')");
         conn1.commit();
         ResultSet rs =
                 conn1.createStatement()
                         .executeQuery(
-                            "select substr(to_char(user_time), 0, 10) as 
ddate, hour(user_time) as hhour, user_id, col1,col2 from "
+                            "select substr(to_char(user_time), 0, 10) as 
ddate, \"HOUR\"(user_time) as hhour, user_id, col1,col2 from "
                                     + tableName2
-                                    + " where hour(user_time)=14 group by 
user_id, col1, col2, ddate, hhour limit 1");
+                                    + " where \"HOUR\"(user_time)=14 group by 
user_id, col1, col2, ddate, hhour limit 1");
         assertTrue(rs.next());
     }
 

http://git-wip-us.apache.org/repos/asf/phoenix/blob/3760be37/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ByteBasedRegexpReplaceFunction.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ByteBasedRegexpReplaceFunction.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ByteBasedRegexpReplaceFunction.java
index c815190..45ab5b0 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ByteBasedRegexpReplaceFunction.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ByteBasedRegexpReplaceFunction.java
@@ -23,7 +23,18 @@ import org.apache.phoenix.expression.Expression;
 import org.apache.phoenix.expression.util.regex.AbstractBasePattern;
 import org.apache.phoenix.expression.util.regex.JONIPattern;
 import org.joni.Option;
+import org.apache.phoenix.schema.types.PVarchar;
+import org.apache.phoenix.parse.FunctionParseNode.BuiltInFunction;
+import org.apache.phoenix.parse.FunctionParseNode.Argument;
+import org.apache.phoenix.parse.FunctionParseNode.FunctionClassType;
 
+@BuiltInFunction(name=RegexpReplaceFunction.NAME,
+        args= {
+        @Argument(allowedTypes={PVarchar.class}),
+        @Argument(allowedTypes={PVarchar.class}),
+        @Argument(allowedTypes={PVarchar.class},defaultValue="null")},
+        classType = FunctionClassType.DERIVED
+)
 public class ByteBasedRegexpReplaceFunction extends RegexpReplaceFunction {
 
     public ByteBasedRegexpReplaceFunction() {

http://git-wip-us.apache.org/repos/asf/phoenix/blob/3760be37/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ByteBasedRegexpSplitFunction.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ByteBasedRegexpSplitFunction.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ByteBasedRegexpSplitFunction.java
index 1a74975..3ed100a 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ByteBasedRegexpSplitFunction.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ByteBasedRegexpSplitFunction.java
@@ -23,7 +23,17 @@ import org.apache.phoenix.expression.Expression;
 import org.apache.phoenix.expression.util.regex.AbstractBaseSplitter;
 import org.apache.phoenix.expression.util.regex.JONIPattern;
 import org.joni.Option;
+import org.apache.phoenix.schema.types.PVarchar;
+import org.apache.phoenix.parse.FunctionParseNode.BuiltInFunction;
+import org.apache.phoenix.parse.FunctionParseNode.Argument;
+import org.apache.phoenix.parse.FunctionParseNode.FunctionClassType;
 
+@BuiltInFunction(name=RegexpSplitFunction.NAME,
+        args= {
+                @Argument(allowedTypes={PVarchar.class}),
+                @Argument(allowedTypes={PVarchar.class})},
+        classType = FunctionClassType.DERIVED
+)
 public class ByteBasedRegexpSplitFunction extends RegexpSplitFunction {
     public ByteBasedRegexpSplitFunction() {
     }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/3760be37/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ByteBasedRegexpSubstrFunction.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ByteBasedRegexpSubstrFunction.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ByteBasedRegexpSubstrFunction.java
index 96e5353..ea4ea2a 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ByteBasedRegexpSubstrFunction.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/ByteBasedRegexpSubstrFunction.java
@@ -23,7 +23,23 @@ import org.apache.phoenix.expression.Expression;
 import org.apache.phoenix.expression.util.regex.AbstractBasePattern;
 import org.apache.phoenix.expression.util.regex.JONIPattern;
 import org.joni.Option;
+import org.apache.phoenix.expression.Expression;
+import org.apache.phoenix.expression.util.regex.AbstractBasePattern;
+import org.apache.phoenix.expression.util.regex.JONIPattern;
+import org.joni.Option;
+import org.apache.phoenix.schema.types.PLong;
+import org.apache.phoenix.schema.types.PVarchar;
+import org.apache.phoenix.parse.FunctionParseNode.BuiltInFunction;
+import org.apache.phoenix.parse.FunctionParseNode.Argument;
+import org.apache.phoenix.parse.FunctionParseNode.FunctionClassType;
 
+@BuiltInFunction(name=RegexpSubstrFunction.NAME,
+        args= {
+                @Argument(allowedTypes={PVarchar.class}),
+                @Argument(allowedTypes={PVarchar.class}),
+                @Argument(allowedTypes={PLong.class}, defaultValue="1")},
+        classType = FunctionClassType.DERIVED
+)
 public class ByteBasedRegexpSubstrFunction extends RegexpSubstrFunction {
     public ByteBasedRegexpSubstrFunction() {
     }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/3760be37/phoenix-core/src/main/java/org/apache/phoenix/expression/function/CeilDateExpression.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/CeilDateExpression.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/CeilDateExpression.java
index 7629409..1b41cb3 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/CeilDateExpression.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/CeilDateExpression.java
@@ -26,6 +26,12 @@ import org.apache.phoenix.expression.Expression;
 import org.apache.phoenix.expression.LiteralExpression;
 import org.apache.phoenix.schema.tuple.Tuple;
 import org.apache.phoenix.schema.types.PDataType;
+import org.apache.phoenix.schema.types.PVarchar;
+import org.apache.phoenix.schema.types.PDate;
+import org.apache.phoenix.schema.types.PInteger;
+import org.apache.phoenix.parse.FunctionParseNode.BuiltInFunction;
+import org.apache.phoenix.parse.FunctionParseNode.Argument;
+import org.apache.phoenix.parse.FunctionParseNode.FunctionClassType;
 
 import com.google.common.collect.Lists;
 
@@ -36,6 +42,14 @@ import com.google.common.collect.Lists;
  * 
  * @since 3.0.0
  */
+@BuiltInFunction(name = CeilFunction.NAME,
+        args = {
+                @Argument(allowedTypes={PDate.class}),
+                @Argument(allowedTypes={PVarchar.class, PInteger.class}, 
defaultValue = "null", isConstant=true),
+                @Argument(allowedTypes={PInteger.class}, defaultValue="1", 
isConstant=true)
+        },
+        classType = FunctionClassType.DERIVED
+)
 public class CeilDateExpression extends RoundDateExpression {
     
     public CeilDateExpression() {}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/3760be37/phoenix-core/src/main/java/org/apache/phoenix/expression/function/CeilDecimalExpression.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/CeilDecimalExpression.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/CeilDecimalExpression.java
index 9c64896..d561b48 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/CeilDecimalExpression.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/CeilDecimalExpression.java
@@ -29,6 +29,11 @@ import org.apache.phoenix.query.KeyRange;
 import org.apache.phoenix.schema.types.PDecimal;
 import org.apache.phoenix.schema.types.PInteger;
 import org.apache.phoenix.schema.types.PLong;
+import org.apache.phoenix.schema.types.PVarchar;
+import org.apache.phoenix.schema.types.PInteger;
+import org.apache.phoenix.parse.FunctionParseNode.BuiltInFunction;
+import org.apache.phoenix.parse.FunctionParseNode.Argument;
+import org.apache.phoenix.parse.FunctionParseNode.FunctionClassType;
 
 import com.google.common.collect.Lists;
 
@@ -39,6 +44,14 @@ import com.google.common.collect.Lists;
  *
  * @since 3.0.0
  */
+@BuiltInFunction(name = CeilFunction.NAME,
+        args = {
+                @Argument(allowedTypes={PDecimal.class}),
+                @Argument(allowedTypes={PVarchar.class, PInteger.class}, 
defaultValue = "null", isConstant=true),
+                @Argument(allowedTypes={PInteger.class}, defaultValue="1", 
isConstant=true)
+        },
+        classType = FunctionClassType.DERIVED
+)
 public class CeilDecimalExpression extends RoundDecimalExpression {
 
     public CeilDecimalExpression() {}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/3760be37/phoenix-core/src/main/java/org/apache/phoenix/expression/function/CeilFunction.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/CeilFunction.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/CeilFunction.java
index b65010a..28fdc15 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/CeilFunction.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/CeilFunction.java
@@ -17,15 +17,21 @@
  */
 package org.apache.phoenix.expression.function;
 
+import java.sql.SQLException;
 import java.util.List;
 
 import org.apache.phoenix.expression.Expression;
 import org.apache.phoenix.parse.CeilParseNode;
+import org.apache.phoenix.parse.FunctionParseNode;
 import org.apache.phoenix.parse.FunctionParseNode.Argument;
 import org.apache.phoenix.parse.FunctionParseNode.BuiltInFunction;
+import org.apache.phoenix.schema.TypeMismatchException;
+import org.apache.phoenix.schema.types.PDataType;
+import org.apache.phoenix.schema.types.PDate;
 import org.apache.phoenix.schema.types.PDecimal;
 import org.apache.phoenix.schema.types.PInteger;
 import org.apache.phoenix.schema.types.PTimestamp;
+import org.apache.phoenix.schema.types.PUnsignedTimestamp;
 import org.apache.phoenix.schema.types.PVarchar;
 
 /**
@@ -41,7 +47,9 @@ import org.apache.phoenix.schema.types.PVarchar;
                         @Argument(allowedTypes={PTimestamp.class, 
PDecimal.class}),
                         @Argument(allowedTypes={PVarchar.class, 
PInteger.class}, defaultValue = "null", isConstant=true),
                         @Argument(allowedTypes={PInteger.class}, 
defaultValue="1", isConstant=true)
-                        } 
+                        },
+                 classType = FunctionParseNode.FunctionClassType.ABSTRACT,
+                 derivedFunctions = {CeilDateExpression.class, 
CeilTimestampExpression.class, CeilDecimalExpression.class}
                 )
 public abstract class CeilFunction extends ScalarFunction {
     

http://git-wip-us.apache.org/repos/asf/phoenix/blob/3760be37/phoenix-core/src/main/java/org/apache/phoenix/expression/function/CeilTimestampExpression.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/CeilTimestampExpression.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/CeilTimestampExpression.java
index b3a2a97..c2b0b9a 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/CeilTimestampExpression.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/CeilTimestampExpression.java
@@ -33,6 +33,11 @@ import org.apache.phoenix.schema.types.PDate;
 import org.apache.phoenix.schema.types.PTimestamp;
 import org.apache.phoenix.schema.types.PUnsignedDate;
 import org.apache.phoenix.schema.types.PUnsignedTimestamp;
+import org.apache.phoenix.schema.types.PVarchar;
+import org.apache.phoenix.schema.types.PInteger;
+import org.apache.phoenix.parse.FunctionParseNode.BuiltInFunction;
+import org.apache.phoenix.parse.FunctionParseNode.Argument;
+import org.apache.phoenix.parse.FunctionParseNode.FunctionClassType;
 
 import com.google.common.collect.Lists;
 
@@ -45,6 +50,14 @@ import com.google.common.collect.Lists;
  * 
  * @since 3.0.0
  */
+@BuiltInFunction(name = CeilFunction.NAME,
+        args = {
+                @Argument(allowedTypes={PTimestamp.class}),
+                @Argument(allowedTypes={PVarchar.class, PInteger.class}, 
defaultValue = "null", isConstant=true),
+                @Argument(allowedTypes={PInteger.class}, defaultValue="1", 
isConstant=true)
+        },
+        classType = FunctionClassType.DERIVED
+)
 public class CeilTimestampExpression extends CeilDateExpression {
     
     public CeilTimestampExpression() {}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/3760be37/phoenix-core/src/main/java/org/apache/phoenix/expression/function/CurrentDateFunction.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/CurrentDateFunction.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/CurrentDateFunction.java
index 57b82e4..eb1fe01 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/CurrentDateFunction.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/CurrentDateFunction.java
@@ -19,13 +19,18 @@ package org.apache.phoenix.expression.function;
 
 import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
 
+import org.apache.phoenix.compile.StatementContext;
 import org.apache.phoenix.expression.CurrentDateTimeFunction;
+import org.apache.phoenix.expression.Expression;
 import org.apache.phoenix.parse.CurrentDateParseNode;
 import org.apache.phoenix.parse.FunctionParseNode.BuiltInFunction;
 import org.apache.phoenix.schema.types.PDate;
 import org.apache.phoenix.schema.types.PDataType;
 import org.apache.phoenix.schema.tuple.Tuple;
 
+import java.sql.SQLException;
+import java.util.List;
+
 
 /**
  * 
@@ -46,6 +51,10 @@ public class CurrentDateFunction extends 
CurrentDateTimeFunction {
         this(System.currentTimeMillis());
     }
 
+    public CurrentDateFunction(List<Expression> children, StatementContext 
context) throws SQLException {
+        this(context.getCurrentTime());
+    }
+
     public CurrentDateFunction(long timeStamp) {
         getDataType().getCodec().encodeLong(timeStamp, currentDate);
     }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/3760be37/phoenix-core/src/main/java/org/apache/phoenix/expression/function/CurrentTimeFunction.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/CurrentTimeFunction.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/CurrentTimeFunction.java
index 12abb3b..f6f17a6 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/CurrentTimeFunction.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/CurrentTimeFunction.java
@@ -19,13 +19,18 @@ package org.apache.phoenix.expression.function;
 
 import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
 
+import org.apache.phoenix.compile.StatementContext;
 import org.apache.phoenix.expression.CurrentDateTimeFunction;
+import org.apache.phoenix.expression.Expression;
 import org.apache.phoenix.parse.CurrentTimeParseNode;
 import org.apache.phoenix.parse.FunctionParseNode.BuiltInFunction;
 import org.apache.phoenix.schema.types.PDataType;
 import org.apache.phoenix.schema.types.PTime;
 import org.apache.phoenix.schema.tuple.Tuple;
 
+import java.sql.SQLException;
+import java.util.List;
+
 
 /**
  * 
@@ -46,6 +51,10 @@ public class CurrentTimeFunction extends 
CurrentDateTimeFunction {
         this(System.currentTimeMillis());
     }
 
+    public CurrentTimeFunction(List<Expression> children, StatementContext 
context) throws SQLException {
+        this(context.getCurrentTime());
+    }
+
     public CurrentTimeFunction(long timeStamp) {
         getDataType().getCodec().encodeLong(timeStamp, currentDate);
     }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/3760be37/phoenix-core/src/main/java/org/apache/phoenix/expression/function/FirstValueFunction.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/FirstValueFunction.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/FirstValueFunction.java
index df9d26b..c19d053 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/FirstValueFunction.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/FirstValueFunction.java
@@ -44,6 +44,10 @@ public class FirstValueFunction extends 
FirstLastValueBaseFunction {
     public FirstValueFunction() {
     }
 
+    public FirstValueFunction(List<Expression> childExpressions) {
+        this(childExpressions, null);
+    }
+
     public FirstValueFunction(List<Expression> childExpressions, 
CountAggregateFunction delegate) {
         super(childExpressions, delegate);
     }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/3760be37/phoenix-core/src/main/java/org/apache/phoenix/expression/function/FloorDateExpression.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/FloorDateExpression.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/FloorDateExpression.java
index c0eca8a..9c0b874 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/FloorDateExpression.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/FloorDateExpression.java
@@ -31,6 +31,11 @@ import org.apache.phoenix.schema.types.PDate;
 import org.apache.phoenix.schema.types.PTimestamp;
 import org.apache.phoenix.schema.types.PUnsignedDate;
 import org.apache.phoenix.schema.types.PUnsignedTimestamp;
+import org.apache.phoenix.schema.types.PVarchar;
+import org.apache.phoenix.schema.types.PInteger;
+import org.apache.phoenix.parse.FunctionParseNode.BuiltInFunction;
+import org.apache.phoenix.parse.FunctionParseNode.Argument;
+import org.apache.phoenix.parse.FunctionParseNode.FunctionClassType;
 
 import com.google.common.collect.Lists;
 
@@ -42,6 +47,14 @@ import com.google.common.collect.Lists;
  * 
  * @since 3.0.0
  */
+@BuiltInFunction(name = FloorFunction.NAME,
+         args = {
+                 @Argument(allowedTypes={PTimestamp.class}),
+                 @Argument(allowedTypes={PVarchar.class, PInteger.class}, 
defaultValue = "null", isConstant=true),
+                 @Argument(allowedTypes={PInteger.class}, defaultValue="1", 
isConstant=true)
+         },
+         classType = FunctionClassType.DERIVED
+        )
 public class FloorDateExpression extends RoundDateExpression {
     
     public FloorDateExpression() {}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/3760be37/phoenix-core/src/main/java/org/apache/phoenix/expression/function/FloorDecimalExpression.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/FloorDecimalExpression.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/FloorDecimalExpression.java
index 7351cca..1ecedc9 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/FloorDecimalExpression.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/FloorDecimalExpression.java
@@ -29,6 +29,11 @@ import org.apache.phoenix.query.KeyRange;
 import org.apache.phoenix.schema.types.PDecimal;
 import org.apache.phoenix.schema.types.PInteger;
 import org.apache.phoenix.schema.types.PLong;
+import org.apache.phoenix.schema.types.PVarchar;
+import org.apache.phoenix.schema.types.PDecimal;
+import org.apache.phoenix.parse.FunctionParseNode.BuiltInFunction;
+import org.apache.phoenix.parse.FunctionParseNode.Argument;
+import org.apache.phoenix.parse.FunctionParseNode.FunctionClassType;
 
 import com.google.common.collect.Lists;
 
@@ -40,6 +45,14 @@ import com.google.common.collect.Lists;
  *
  * @since 3.0.0
  */
+@BuiltInFunction(name = FloorFunction.NAME,
+        args = {
+                @Argument(allowedTypes={PDecimal.class}),
+                @Argument(allowedTypes={PVarchar.class, PInteger.class}, 
defaultValue = "null", isConstant=true),
+                @Argument(allowedTypes={PInteger.class}, defaultValue="1", 
isConstant=true)
+        },
+        classType = FunctionClassType.DERIVED
+)
 public class FloorDecimalExpression extends RoundDecimalExpression {
 
     public FloorDecimalExpression() {}

http://git-wip-us.apache.org/repos/asf/phoenix/blob/3760be37/phoenix-core/src/main/java/org/apache/phoenix/expression/function/FloorFunction.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/FloorFunction.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/FloorFunction.java
index f6baa09..2072a4a 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/FloorFunction.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/FloorFunction.java
@@ -21,6 +21,7 @@ import java.util.List;
 
 import org.apache.phoenix.expression.Expression;
 import org.apache.phoenix.parse.FloorParseNode;
+import org.apache.phoenix.parse.FunctionParseNode;
 import org.apache.phoenix.parse.FunctionParseNode.Argument;
 import org.apache.phoenix.parse.FunctionParseNode.BuiltInFunction;
 import org.apache.phoenix.schema.types.PDecimal;
@@ -39,7 +40,9 @@ import org.apache.phoenix.schema.types.PVarchar;
                         @Argument(allowedTypes={PTimestamp.class, 
PDecimal.class}),
                         @Argument(allowedTypes={PVarchar.class, 
PInteger.class}, defaultValue = "null", isConstant=true),
                         @Argument(allowedTypes={PInteger.class}, 
defaultValue="1", isConstant=true)
-                        } 
+                        },
+                 classType = FunctionParseNode.FunctionClassType.ABSTRACT,
+                 derivedFunctions = {FloorDateExpression.class, 
FloorDecimalExpression.class}
                 )
 public abstract class FloorFunction extends ScalarFunction {
     

http://git-wip-us.apache.org/repos/asf/phoenix/blob/3760be37/phoenix-core/src/main/java/org/apache/phoenix/expression/function/LastValueFunction.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/LastValueFunction.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/LastValueFunction.java
index 9f01c61..ab6ebe3 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/LastValueFunction.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/LastValueFunction.java
@@ -44,6 +44,10 @@ public class LastValueFunction extends 
FirstLastValueBaseFunction {
     public LastValueFunction() {
     }
 
+    public LastValueFunction(List<Expression> childExpressions) {
+        this(childExpressions, null);
+    }
+
     public LastValueFunction(List<Expression> childExpressions, 
CountAggregateFunction delegate) {
         super(childExpressions, delegate);
     }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/3760be37/phoenix-core/src/main/java/org/apache/phoenix/expression/function/MaxAggregateFunction.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/MaxAggregateFunction.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/MaxAggregateFunction.java
index 4913f91..63252d7 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/MaxAggregateFunction.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/MaxAggregateFunction.java
@@ -43,6 +43,10 @@ public class MaxAggregateFunction extends 
MinAggregateFunction {
 
     public MaxAggregateFunction() {
     }
+
+    public MaxAggregateFunction(List<Expression> childExpressions) {
+        this(childExpressions, null);
+    }
     
     public MaxAggregateFunction(List<Expression> childExpressions, 
CountAggregateFunction delegate) {
         super(childExpressions, delegate);

http://git-wip-us.apache.org/repos/asf/phoenix/blob/3760be37/phoenix-core/src/main/java/org/apache/phoenix/expression/function/MinAggregateFunction.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/MinAggregateFunction.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/MinAggregateFunction.java
index 5b99e13..b26a886 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/MinAggregateFunction.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/MinAggregateFunction.java
@@ -45,6 +45,10 @@ public class MinAggregateFunction extends 
DelegateConstantToCountAggregateFuncti
 
     public MinAggregateFunction() {
     }
+
+    public MinAggregateFunction(List<Expression> childExpressions) {
+        super(childExpressions, null);
+    }
     
     public MinAggregateFunction(List<Expression> childExpressions, 
CountAggregateFunction delegate) {
         super(childExpressions, delegate);

http://git-wip-us.apache.org/repos/asf/phoenix/blob/3760be37/phoenix-core/src/main/java/org/apache/phoenix/expression/function/NowFunction.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/NowFunction.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/NowFunction.java
index 83a5e53..3b7aebb 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/NowFunction.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/NowFunction.java
@@ -20,9 +20,12 @@ package org.apache.phoenix.expression.function;
 import java.sql.SQLException;
 import java.util.List;
 
+import org.apache.phoenix.compile.StatementContext;
 import org.apache.phoenix.expression.Expression;
 import org.apache.phoenix.parse.CurrentDateParseNode;
 import org.apache.phoenix.parse.FunctionParseNode.BuiltInFunction;
+import org.apache.phoenix.parse.FunctionParseNode.FunctionClassType;
+
 
 /**
  * 
@@ -31,7 +34,7 @@ import 
org.apache.phoenix.parse.FunctionParseNode.BuiltInFunction;
  *
  */
 @BuiltInFunction(name = NowFunction.NAME,
-nodeClass=CurrentDateParseNode.class, args= {})
+        nodeClass=CurrentDateParseNode.class, args= {}, classType = 
FunctionClassType.ALIAS, derivedFunctions = {CurrentDateFunction.class})
 public abstract class NowFunction extends ScalarFunction {
     
     public static final String NAME = "NOW";

http://git-wip-us.apache.org/repos/asf/phoenix/blob/3760be37/phoenix-core/src/main/java/org/apache/phoenix/expression/function/NthValueFunction.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/NthValueFunction.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/NthValueFunction.java
index 969fda9..39a09e7 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/NthValueFunction.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/NthValueFunction.java
@@ -47,6 +47,10 @@ public class NthValueFunction extends 
FirstLastValueBaseFunction {
     public NthValueFunction() {
     }
 
+    public NthValueFunction(List<Expression> childExpressions) {
+        this(childExpressions, null);
+    }
+
     public NthValueFunction(List<Expression> childExpressions, 
CountAggregateFunction delegate) {
         super(childExpressions, delegate);
     }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/3760be37/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RegexpReplaceFunction.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RegexpReplaceFunction.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RegexpReplaceFunction.java
index b5a3d39..f2ab8f3 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RegexpReplaceFunction.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RegexpReplaceFunction.java
@@ -25,6 +25,7 @@ import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
 import org.apache.phoenix.expression.Determinism;
 import org.apache.phoenix.expression.Expression;
 import org.apache.phoenix.expression.util.regex.AbstractBasePattern;
+import org.apache.phoenix.parse.FunctionParseNode;
 import org.apache.phoenix.parse.FunctionParseNode.Argument;
 import org.apache.phoenix.parse.FunctionParseNode.BuiltInFunction;
 import org.apache.phoenix.parse.RegexpReplaceParseNode;
@@ -53,7 +54,9 @@ import org.apache.phoenix.schema.types.PVarchar;
     nodeClass = RegexpReplaceParseNode.class, args= {
     @Argument(allowedTypes={PVarchar.class}),
     @Argument(allowedTypes={PVarchar.class}),
-    @Argument(allowedTypes={PVarchar.class},defaultValue="null")} )
+    @Argument(allowedTypes={PVarchar.class},defaultValue="null")},
+    classType = FunctionParseNode.FunctionClassType.ABSTRACT,
+    derivedFunctions = {ByteBasedRegexpReplaceFunction.class, 
StringBasedRegexpReplaceFunction.class})
 public abstract class RegexpReplaceFunction extends ScalarFunction {
     public static final String NAME = "REGEXP_REPLACE";
 

http://git-wip-us.apache.org/repos/asf/phoenix/blob/3760be37/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RegexpSplitFunction.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RegexpSplitFunction.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RegexpSplitFunction.java
index c663188..e86fe3b 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RegexpSplitFunction.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RegexpSplitFunction.java
@@ -48,7 +48,9 @@ import org.apache.phoenix.util.ByteUtil;
  @FunctionParseNode.BuiltInFunction(name=RegexpSplitFunction.NAME,
         nodeClass = RegexpSplitParseNode.class, args= {
         @FunctionParseNode.Argument(allowedTypes={PVarchar.class}),
-        @FunctionParseNode.Argument(allowedTypes={PVarchar.class})})
+        @FunctionParseNode.Argument(allowedTypes={PVarchar.class})},
+        classType = FunctionParseNode.FunctionClassType.ABSTRACT,
+        derivedFunctions = {ByteBasedRegexpSplitFunction.class, 
StringBasedRegexpSplitFunction.class})
 public abstract class RegexpSplitFunction extends ScalarFunction {
 
     public static final String NAME = "REGEXP_SPLIT";

http://git-wip-us.apache.org/repos/asf/phoenix/blob/3760be37/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RegexpSubstrFunction.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RegexpSubstrFunction.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RegexpSubstrFunction.java
index ea80b11..466fd1a 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RegexpSubstrFunction.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RegexpSubstrFunction.java
@@ -25,6 +25,7 @@ import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
 import org.apache.phoenix.expression.Determinism;
 import org.apache.phoenix.expression.Expression;
 import org.apache.phoenix.expression.util.regex.AbstractBasePattern;
+import org.apache.phoenix.parse.FunctionParseNode;
 import org.apache.phoenix.parse.FunctionParseNode.Argument;
 import org.apache.phoenix.parse.FunctionParseNode.BuiltInFunction;
 import org.apache.phoenix.parse.RegexpSubstrParseNode;
@@ -52,7 +53,9 @@ import org.apache.phoenix.schema.types.PVarchar;
     nodeClass = RegexpSubstrParseNode.class, args={
     @Argument(allowedTypes={PVarchar.class}),
     @Argument(allowedTypes={PVarchar.class}),
-    @Argument(allowedTypes={PLong.class}, defaultValue="1")} )
+    @Argument(allowedTypes={PLong.class}, defaultValue="1")},
+    classType = FunctionParseNode.FunctionClassType.ABSTRACT,
+    derivedFunctions = {ByteBasedRegexpSubstrFunction.class, 
StringBasedRegexpSubstrFunction.class})
 public abstract class RegexpSubstrFunction extends PrefixFunction {
     public static final String NAME = "REGEXP_SUBSTR";
 

http://git-wip-us.apache.org/repos/asf/phoenix/blob/3760be37/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RoundDateExpression.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RoundDateExpression.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RoundDateExpression.java
index 069bf60..d747771 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RoundDateExpression.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RoundDateExpression.java
@@ -42,6 +42,10 @@ import org.apache.phoenix.schema.types.PDataType.PDataCodec;
 import org.apache.phoenix.schema.types.PInteger;
 import org.apache.phoenix.schema.types.PVarchar;
 import org.apache.phoenix.util.ByteUtil;
+import org.apache.phoenix.schema.types.PDate;
+import org.apache.phoenix.parse.FunctionParseNode.BuiltInFunction;
+import org.apache.phoenix.parse.FunctionParseNode.Argument;
+import org.apache.phoenix.parse.FunctionParseNode.FunctionClassType;
 
 import com.google.common.collect.Lists;
 
@@ -55,6 +59,14 @@ import com.google.common.collect.Lists;
  * 
  * @since 0.1
  */
+@BuiltInFunction(name = RoundFunction.NAME,
+        args = {
+                @Argument(allowedTypes={PDate.class}),
+                @Argument(allowedTypes={PVarchar.class, PInteger.class}, 
defaultValue = "null", isConstant=true),
+                @Argument(allowedTypes={PInteger.class}, defaultValue="1", 
isConstant=true)
+        },
+        classType = FunctionClassType.DERIVED
+)
 public class RoundDateExpression extends ScalarFunction {
     
     long divBy;

http://git-wip-us.apache.org/repos/asf/phoenix/blob/3760be37/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RoundDecimalExpression.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RoundDecimalExpression.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RoundDecimalExpression.java
index 055535e..324d655 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RoundDecimalExpression.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RoundDecimalExpression.java
@@ -42,6 +42,10 @@ import org.apache.phoenix.schema.types.PDataType;
 import org.apache.phoenix.schema.types.PDecimal;
 import org.apache.phoenix.schema.types.PInteger;
 import org.apache.phoenix.schema.types.PLong;
+import org.apache.phoenix.schema.types.PVarchar;
+import org.apache.phoenix.parse.FunctionParseNode.BuiltInFunction;
+import org.apache.phoenix.parse.FunctionParseNode.Argument;
+import org.apache.phoenix.parse.FunctionParseNode.FunctionClassType;
 
 import com.google.common.collect.Lists;
 
@@ -53,6 +57,14 @@ import com.google.common.collect.Lists;
  *
  * @since 3.0.0
  */
+@BuiltInFunction(name = RoundFunction.NAME,
+        args = {
+                @Argument(allowedTypes={PDecimal.class}),
+                @Argument(allowedTypes={PVarchar.class, PInteger.class}, 
defaultValue = "null", isConstant=true),
+                @Argument(allowedTypes={PInteger.class}, defaultValue="1", 
isConstant=true)
+        },
+        classType = FunctionClassType.DERIVED
+)
 public class RoundDecimalExpression extends ScalarFunction {
 
     private int scale;

http://git-wip-us.apache.org/repos/asf/phoenix/blob/3760be37/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RoundFunction.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RoundFunction.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RoundFunction.java
index 7d0306c..d95a396 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RoundFunction.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RoundFunction.java
@@ -20,6 +20,7 @@ package org.apache.phoenix.expression.function;
 import java.util.List;
 
 import org.apache.phoenix.expression.Expression;
+import org.apache.phoenix.parse.FunctionParseNode;
 import org.apache.phoenix.parse.FunctionParseNode.Argument;
 import org.apache.phoenix.parse.FunctionParseNode.BuiltInFunction;
 import org.apache.phoenix.parse.RoundParseNode;
@@ -38,7 +39,9 @@ import org.apache.phoenix.schema.types.PVarchar;
                         @Argument(allowedTypes={PTimestamp.class, 
PDecimal.class}),
                         @Argument(allowedTypes={PVarchar.class, 
PInteger.class}, defaultValue = "null", isConstant=true),
                         @Argument(allowedTypes={PInteger.class}, 
defaultValue="1", isConstant=true)
-                        } 
+                        },
+                 classType = FunctionParseNode.FunctionClassType.ABSTRACT,
+                 derivedFunctions = {RoundDateExpression.class, 
RoundTimestampExpression.class, RoundDecimalExpression.class}
                 )
 public abstract class RoundFunction extends ScalarFunction {
     

http://git-wip-us.apache.org/repos/asf/phoenix/blob/3760be37/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RoundTimestampExpression.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RoundTimestampExpression.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RoundTimestampExpression.java
index 7b5ba93..51537b4 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RoundTimestampExpression.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/RoundTimestampExpression.java
@@ -33,6 +33,11 @@ import org.apache.phoenix.schema.types.PDate;
 import org.apache.phoenix.schema.types.PTimestamp;
 import org.apache.phoenix.schema.types.PUnsignedDate;
 import org.apache.phoenix.schema.types.PUnsignedTimestamp;
+import org.apache.phoenix.schema.types.PVarchar;
+import org.apache.phoenix.schema.types.PInteger;
+import org.apache.phoenix.parse.FunctionParseNode.BuiltInFunction;
+import org.apache.phoenix.parse.FunctionParseNode.Argument;
+import org.apache.phoenix.parse.FunctionParseNode.FunctionClassType;
 
 import com.google.common.collect.Lists;
 
@@ -47,7 +52,14 @@ import com.google.common.collect.Lists;
  * 
  * @since 3.0.0
  */
-
+@BuiltInFunction(name = RoundFunction.NAME,
+        args = {
+                @Argument(allowedTypes={PTimestamp.class}),
+                @Argument(allowedTypes={PVarchar.class, PInteger.class}, 
defaultValue = "null", isConstant=true),
+                @Argument(allowedTypes={PInteger.class}, defaultValue="1", 
isConstant=true)
+        },
+        classType = FunctionClassType.DERIVED
+)
 public class RoundTimestampExpression extends RoundDateExpression {
     
     private static final long HALF_OF_NANOS_IN_MILLI = 
java.util.concurrent.TimeUnit.MILLISECONDS.toNanos(1)/2;

http://git-wip-us.apache.org/repos/asf/phoenix/blob/3760be37/phoenix-core/src/main/java/org/apache/phoenix/expression/function/StringBasedRegexpReplaceFunction.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/StringBasedRegexpReplaceFunction.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/StringBasedRegexpReplaceFunction.java
index 1e4943f..89f8bea 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/StringBasedRegexpReplaceFunction.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/StringBasedRegexpReplaceFunction.java
@@ -24,6 +24,18 @@ import org.apache.phoenix.expression.Expression;
 import org.apache.phoenix.expression.util.regex.AbstractBasePattern;
 import org.apache.phoenix.expression.util.regex.JavaPattern;
 
+import org.apache.phoenix.schema.types.PVarchar;
+import org.apache.phoenix.parse.FunctionParseNode.BuiltInFunction;
+import org.apache.phoenix.parse.FunctionParseNode.Argument;
+import org.apache.phoenix.parse.FunctionParseNode.FunctionClassType;
+
+@BuiltInFunction(name=RegexpReplaceFunction.NAME,
+        args= {
+                @Argument(allowedTypes={PVarchar.class}),
+                @Argument(allowedTypes={PVarchar.class}),
+                @Argument(allowedTypes={PVarchar.class},defaultValue="null")},
+        classType = FunctionClassType.DERIVED
+)
 public class StringBasedRegexpReplaceFunction extends RegexpReplaceFunction {
 
     public StringBasedRegexpReplaceFunction() {

http://git-wip-us.apache.org/repos/asf/phoenix/blob/3760be37/phoenix-core/src/main/java/org/apache/phoenix/expression/function/StringBasedRegexpSplitFunction.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/StringBasedRegexpSplitFunction.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/StringBasedRegexpSplitFunction.java
index 77321c2..029a5d3 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/StringBasedRegexpSplitFunction.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/StringBasedRegexpSplitFunction.java
@@ -22,7 +22,17 @@ import java.util.List;
 import org.apache.phoenix.expression.Expression;
 import org.apache.phoenix.expression.util.regex.AbstractBaseSplitter;
 import org.apache.phoenix.expression.util.regex.GuavaSplitter;
+import org.apache.phoenix.schema.types.PVarchar;
+import org.apache.phoenix.parse.FunctionParseNode.BuiltInFunction;
+import org.apache.phoenix.parse.FunctionParseNode.Argument;
+import org.apache.phoenix.parse.FunctionParseNode.FunctionClassType;
 
+@BuiltInFunction(name=RegexpSplitFunction.NAME,
+        args= {
+                @Argument(allowedTypes={PVarchar.class}),
+                @Argument(allowedTypes={PVarchar.class})},
+        classType = FunctionClassType.DERIVED
+)
 public class StringBasedRegexpSplitFunction extends RegexpSplitFunction {
     public StringBasedRegexpSplitFunction() {
     }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/3760be37/phoenix-core/src/main/java/org/apache/phoenix/expression/function/StringBasedRegexpSubstrFunction.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/StringBasedRegexpSubstrFunction.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/StringBasedRegexpSubstrFunction.java
index 5e82a32..de2e0d4 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/StringBasedRegexpSubstrFunction.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/StringBasedRegexpSubstrFunction.java
@@ -23,7 +23,19 @@ import java.util.regex.Pattern;
 import org.apache.phoenix.expression.Expression;
 import org.apache.phoenix.expression.util.regex.AbstractBasePattern;
 import org.apache.phoenix.expression.util.regex.JavaPattern;
+import org.apache.phoenix.schema.types.PLong;
+import org.apache.phoenix.schema.types.PVarchar;
+import org.apache.phoenix.parse.FunctionParseNode.BuiltInFunction;
+import org.apache.phoenix.parse.FunctionParseNode.Argument;
+import org.apache.phoenix.parse.FunctionParseNode.FunctionClassType;
 
+@BuiltInFunction(name=RegexpSubstrFunction.NAME,
+        args= {
+                @Argument(allowedTypes={PVarchar.class}),
+                @Argument(allowedTypes={PVarchar.class}),
+                @Argument(allowedTypes={PLong.class}, defaultValue="1")},
+        classType = FunctionClassType.DERIVED
+)
 public class StringBasedRegexpSubstrFunction extends RegexpSubstrFunction {
     public StringBasedRegexpSubstrFunction() {
     }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/3760be37/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 be40723..317620f 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
@@ -26,7 +26,9 @@ import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
 import org.apache.hadoop.io.WritableUtils;
 
 import com.google.common.base.Preconditions;
+import org.apache.phoenix.compile.StatementContext;
 import org.apache.phoenix.expression.Expression;
+import org.apache.phoenix.expression.LiteralExpression;
 import org.apache.phoenix.parse.FunctionParseNode.Argument;
 import org.apache.phoenix.parse.FunctionParseNode.BuiltInFunction;
 import org.apache.phoenix.parse.*;
@@ -57,6 +59,38 @@ public class ToCharFunction extends ScalarFunction {
     public ToCharFunction() {
     }
 
+    public ToCharFunction(List<Expression> children, StatementContext context) 
throws SQLException {
+        super(children.subList(0, 1));
+        PDataType dataType = children.get(0).getDataType();
+        String formatString = 
(String)((LiteralExpression)children.get(1)).getValue(); // either date or 
number format string
+        Format formatter;
+        FunctionArgumentType type;
+        if (dataType.isCoercibleTo(PTimestamp.INSTANCE)) {
+            if (formatString == null) {
+                formatString = context.getDateFormat();
+                formatter = context.getDateFormatter();
+            } else {
+                formatter = 
FunctionArgumentType.TEMPORAL.getFormatter(formatString);
+            }
+            type = FunctionArgumentType.TEMPORAL;
+        }
+        else if (dataType.isCoercibleTo(PDecimal.INSTANCE)) {
+            if (formatString == null)
+                formatString = context.getNumberFormat();
+            formatter = 
FunctionArgumentType.NUMERIC.getFormatter(formatString);
+            type = FunctionArgumentType.NUMERIC;
+        }
+        else {
+            throw new SQLException(dataType + " type is unsupported for 
TO_CHAR().  Numeric and temporal types are supported.");
+        }
+        Preconditions.checkNotNull(formatString);
+        Preconditions.checkNotNull(formatter);
+        Preconditions.checkNotNull(type);
+        this.type = type;
+        this.formatString = formatString;
+        this.formatter = formatter;
+    }
+
     public ToCharFunction(List<Expression> children, FunctionArgumentType 
type, String formatString, Format formatter) throws SQLException {
         super(children.subList(0, 1));
         Preconditions.checkNotNull(formatString);

http://git-wip-us.apache.org/repos/asf/phoenix/blob/3760be37/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 1930d92..3df09bf 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
@@ -25,6 +25,7 @@ import java.util.List;
 
 import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
 import org.apache.hadoop.io.WritableUtils;
+import org.apache.phoenix.compile.StatementContext;
 import org.apache.phoenix.expression.Expression;
 import org.apache.phoenix.expression.LiteralExpression;
 import org.apache.phoenix.parse.FunctionParseNode.Argument;
@@ -61,6 +62,19 @@ public class ToDateFunction extends ScalarFunction {
     public ToDateFunction() {
     }
 
+    public ToDateFunction(List<Expression> children, StatementContext context) 
throws SQLException {
+        super(children);
+        String dateFormat = (String) ((LiteralExpression) 
children.get(1)).getValue();
+        String timeZoneId = (String) ((LiteralExpression) 
children.get(2)).getValue();
+        if (dateFormat == null) {
+            dateFormat = context.getDateFormat();
+        }
+        if (timeZoneId == null) {
+            timeZoneId = context.getDateFormatTimeZone().getID();
+        }
+        init(dateFormat, timeZoneId);
+    }
+
     public ToDateFunction(List<Expression> children, String dateFormat, String 
timeZoneId) throws SQLException {
         super(children);
         init(dateFormat, timeZoneId);

http://git-wip-us.apache.org/repos/asf/phoenix/blob/3760be37/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 c43062f..24e8d73 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
@@ -31,10 +31,13 @@ import org.apache.hadoop.io.WritableUtils;
 
 import com.google.common.base.Preconditions;
 
+import org.apache.phoenix.compile.StatementContext;
 import org.apache.phoenix.expression.Expression;
+import org.apache.phoenix.expression.LiteralExpression;
 import org.apache.phoenix.parse.FunctionParseNode.Argument;
 import org.apache.phoenix.parse.FunctionParseNode.BuiltInFunction;
 import org.apache.phoenix.parse.*;
+import org.apache.phoenix.schema.types.PChar;
 import org.apache.phoenix.schema.types.PDecimal;
 import org.apache.phoenix.schema.types.PDataType;
 import org.apache.phoenix.schema.types.PTimestamp;
@@ -61,6 +64,37 @@ public class ToNumberFunction extends ScalarFunction {
     
     public ToNumberFunction() {}
 
+    public ToNumberFunction(List<Expression> children, StatementContext 
context) throws SQLException {
+        super(children.subList(0, 1));
+        PDataType dataType = children.get(0).getDataType();
+        String formatString = 
(String)((LiteralExpression)children.get(1)).getValue(); // either date or 
number format string
+        Format formatter =  null;
+        FunctionArgumentType type;
+
+        if (dataType.isCoercibleTo(PTimestamp.INSTANCE)) {
+            if (formatString == null) {
+                formatString = context.getDateFormat();
+                formatter = context.getDateFormatter();
+            } else {
+                formatter = 
FunctionArgumentType.TEMPORAL.getFormatter(formatString);
+            }
+            type = FunctionArgumentType.TEMPORAL;
+        }
+        else if (dataType.isCoercibleTo(PChar.INSTANCE)) {
+            if (formatString != null) {
+                formatter = 
FunctionArgumentType.CHAR.getFormatter(formatString);
+            }
+            type = FunctionArgumentType.CHAR;
+        }
+        else {
+            throw new SQLException(dataType + " type is unsupported for 
TO_NUMBER().  Numeric and temporal types are supported.");
+        }
+        Preconditions.checkNotNull(type);
+        this.type = type;
+        this.formatString = formatString;
+        this.format = formatter;
+    }
+
     public ToNumberFunction(List<Expression> children, FunctionArgumentType 
type, String formatString, Format formatter) throws SQLException {
         super(children.subList(0, 1));
         Preconditions.checkNotNull(type);

http://git-wip-us.apache.org/repos/asf/phoenix/blob/3760be37/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 588cb92..905d955 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
@@ -20,7 +20,9 @@ package org.apache.phoenix.expression.function;
 import java.sql.SQLException;
 import java.util.List;
 
+import org.apache.phoenix.compile.StatementContext;
 import org.apache.phoenix.expression.Expression;
+import org.apache.phoenix.expression.LiteralExpression;
 import org.apache.phoenix.parse.FunctionParseNode.Argument;
 import org.apache.phoenix.parse.FunctionParseNode.BuiltInFunction;
 import org.apache.phoenix.parse.ToTimeParseNode;
@@ -47,6 +49,10 @@ public class ToTimeFunction extends ToDateFunction {
     public ToTimeFunction() {
     }
 
+    public ToTimeFunction(List<Expression> children, StatementContext context) 
throws SQLException {
+        super(children, context);
+    }
+
     public ToTimeFunction(List<Expression> children, String dateFormat, String 
timeZoneId) throws SQLException {
         super(children, dateFormat, timeZoneId);
     }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/3760be37/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 6c14595..a727d0e 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
@@ -20,6 +20,7 @@ package org.apache.phoenix.expression.function;
 import java.sql.SQLException;
 import java.util.List;
 
+import org.apache.phoenix.compile.StatementContext;
 import org.apache.phoenix.expression.Expression;
 import org.apache.phoenix.parse.FunctionParseNode.Argument;
 import org.apache.phoenix.parse.FunctionParseNode.BuiltInFunction;
@@ -47,6 +48,10 @@ public class ToTimestampFunction extends ToDateFunction {
     public ToTimestampFunction() {
     }
 
+    public ToTimestampFunction(List<Expression> children, StatementContext 
context) throws SQLException {
+        super(children, context);
+    }
+
     public ToTimestampFunction(List<Expression> children, String dateFormat, 
String timeZoneId) throws SQLException {
         super(children, dateFormat, timeZoneId);
     }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/3760be37/phoenix-core/src/main/java/org/apache/phoenix/expression/function/TruncFunction.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/TruncFunction.java
 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/TruncFunction.java
index 3b9616c..83297a1 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/expression/function/TruncFunction.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/expression/function/TruncFunction.java
@@ -22,6 +22,7 @@ import java.util.List;
 
 import org.apache.phoenix.expression.Expression;
 import org.apache.phoenix.parse.FloorParseNode;
+import org.apache.phoenix.parse.FunctionParseNode;
 import org.apache.phoenix.parse.FunctionParseNode.Argument;
 import org.apache.phoenix.parse.FunctionParseNode.BuiltInFunction;
 import org.apache.phoenix.schema.types.PDecimal;
@@ -46,7 +47,9 @@ args = {
        @Argument(allowedTypes={PTimestamp.class, PDecimal.class}),
        @Argument(allowedTypes={PVarchar.class, PInteger.class}, defaultValue = 
"null", isConstant=true),
        @Argument(allowedTypes={PInteger.class}, defaultValue="1", 
isConstant=true)
-       } 
+       },
+classType = FunctionParseNode.FunctionClassType.ALIAS,
+derivedFunctions = {FloorFunction.class}
 )
 public abstract class TruncFunction extends ScalarFunction {
     

http://git-wip-us.apache.org/repos/asf/phoenix/blob/3760be37/phoenix-core/src/main/java/org/apache/phoenix/parse/FunctionParseNode.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/parse/FunctionParseNode.java 
b/phoenix-core/src/main/java/org/apache/phoenix/parse/FunctionParseNode.java
index 952d0d3..df9ad86 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/parse/FunctionParseNode.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/FunctionParseNode.java
@@ -283,6 +283,8 @@ public class FunctionParseNode extends CompoundParseNode {
         String name();
         Argument[] args() default {};
         Class<? extends FunctionParseNode> nodeClass() default 
FunctionParseNode.class;
+        Class<? extends FunctionExpression>[] derivedFunctions() default {};
+        FunctionClassType classType() default FunctionClassType.NONE;
     }
 
     @Retention(RetentionPolicy.RUNTIME)
@@ -297,20 +299,32 @@ public class FunctionParseNode extends CompoundParseNode {
         String maxValue() default "";
     }
 
+    public enum FunctionClassType {
+        NONE,
+        ABSTRACT,
+        DERIVED,
+        ALIAS,
+        UDF
+    }
+
     /**
      * Structure used to hold parse-time information about Function 
implementation classes
      */
     @Immutable
     public static final class BuiltInFunctionInfo {
         private final String name;
+        private final Class<? extends FunctionExpression> func;
         private final Constructor<? extends FunctionExpression> funcCtor;
         private final Constructor<? extends FunctionParseNode> nodeCtor;
         private final BuiltInFunctionArgInfo[] args;
         private final boolean isAggregate;
         private final int requiredArgCount;
+        private final FunctionClassType classType;
+        private final Class<? extends FunctionExpression>[] derivedFunctions;
 
         public BuiltInFunctionInfo(Class<? extends FunctionExpression> f, 
BuiltInFunction d) {
             this.name = SchemaUtil.normalizeIdentifier(d.name());
+            this.func = f;
             this.funcCtor = d.nodeClass() == FunctionParseNode.class ? 
getExpressionCtor(f, null) : null;
             this.nodeCtor = d.nodeClass() == FunctionParseNode.class ? null : 
getParseNodeCtor(d.nodeClass());
             this.args = new BuiltInFunctionArgInfo[d.args().length];
@@ -323,10 +337,13 @@ public class FunctionParseNode extends CompoundParseNode {
             }
             this.requiredArgCount = requiredArgCount;
             this.isAggregate = AggregateFunction.class.isAssignableFrom(f);
+            this.classType = d.classType();
+            this.derivedFunctions = d.derivedFunctions();
         }
 
         public BuiltInFunctionInfo(PFunction function) {
             this.name = 
SchemaUtil.normalizeIdentifier(function.getFunctionName());
+            this.func = null;
             this.funcCtor = getExpressionCtor(UDFExpression.class, function);
             this.nodeCtor = getParseNodeCtor(UDFParseNode.class);
             this.args = new 
BuiltInFunctionArgInfo[function.getFunctionArguments().size()];
@@ -339,6 +356,8 @@ public class FunctionParseNode extends CompoundParseNode {
             }
             this.requiredArgCount = requiredArgCount;
             this.isAggregate = 
AggregateFunction.class.isAssignableFrom(UDFExpression.class);
+            this.classType = FunctionClassType.UDF;
+            this.derivedFunctions = null;
         }
 
         public int getRequiredArgCount() {
@@ -349,6 +368,10 @@ public class FunctionParseNode extends CompoundParseNode {
             return name;
         }
 
+        public Class<? extends FunctionExpression> getFunc() {
+            return func;
+        }
+
         public Constructor<? extends FunctionExpression> getFuncCtor() {
             return funcCtor;
         }
@@ -364,6 +387,14 @@ public class FunctionParseNode extends CompoundParseNode {
         public BuiltInFunctionArgInfo[] getArgs() {
             return args;
         }
+
+        public FunctionClassType getClassType() {
+            return classType;
+        }
+
+        public Class<? extends FunctionExpression>[] getDerivedFunctions() {
+            return derivedFunctions;
+        }
     }
 
     @Immutable

http://git-wip-us.apache.org/repos/asf/phoenix/blob/3760be37/phoenix-core/src/main/java/org/apache/phoenix/parse/ParseNodeFactory.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/parse/ParseNodeFactory.java 
b/phoenix-core/src/main/java/org/apache/phoenix/parse/ParseNodeFactory.java
index da38abd..0c60e39 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/parse/ParseNodeFactory.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/ParseNodeFactory.java
@@ -25,8 +25,10 @@ import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Collection;
 import java.util.concurrent.atomic.AtomicInteger;
 
+import com.google.common.collect.ArrayListMultimap;
 import org.apache.hadoop.hbase.filter.CompareFilter.CompareOp;
 import org.apache.hadoop.hbase.util.Pair;
 import org.apache.phoenix.expression.Expression;
@@ -55,6 +57,7 @@ import org.apache.phoenix.util.SchemaUtil;
 import com.google.common.collect.ListMultimap;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
+import com.google.common.collect.Multimap;
 
 /**
  * 
@@ -73,6 +76,7 @@ public class ParseNodeFactory {
         AvgAggregateFunction.class
         );
     private static final Map<BuiltInFunctionKey, BuiltInFunctionInfo> 
BUILT_IN_FUNCTION_MAP = Maps.newHashMap();
+    private static final Multimap<String, BuiltInFunctionInfo> 
BUILT_IN_FUNCTION_MULTIMAP = ArrayListMultimap.create();
     private static final BigDecimal MAX_LONG = 
BigDecimal.valueOf(Long.MAX_VALUE);
 
 
@@ -127,19 +131,24 @@ public class ParseNodeFactory {
         }
         int nArgs = d.args().length;
         BuiltInFunctionInfo value = new BuiltInFunctionInfo(f, d);
-        do {
-            // Add function to function map, throwing if conflicts found
-            // Add entry for each possible version of function based on 
arguments that are not required to be present (i.e. arg with default value)
-            BuiltInFunctionKey key = new BuiltInFunctionKey(value.getName(), 
nArgs);
-            if (BUILT_IN_FUNCTION_MAP.put(key, value) != null) {
-                throw new IllegalStateException("Multiple " + value.getName() 
+ " functions with " + nArgs + " arguments");
-            }
-        } while (--nArgs >= 0 && d.args()[nArgs].defaultValue().length() > 0);
+        if (d.classType() != FunctionParseNode.FunctionClassType.ABSTRACT) {
+            BUILT_IN_FUNCTION_MULTIMAP.put(value.getName(), value);
+        }
+        if (d.classType() != FunctionParseNode.FunctionClassType.DERIVED) {
+            do {
+                // Add function to function map, throwing if conflicts found
+                // Add entry for each possible version of function based on 
arguments that are not required to be present (i.e. arg with default value)
+                BuiltInFunctionKey key = new 
BuiltInFunctionKey(value.getName(), nArgs);
+                if (BUILT_IN_FUNCTION_MAP.put(key, value) != null) {
+                    throw new IllegalStateException("Multiple " + 
value.getName() + " functions with " + nArgs + " arguments");
+                }
+            } while (--nArgs >= 0 && d.args()[nArgs].defaultValue().length() > 
0);
 
-        // Look for default values that aren't at the end and throw
-        while (--nArgs >= 0) {
-            if (d.args()[nArgs].defaultValue().length() > 0) {
-                throw new IllegalStateException("Function " + value.getName() 
+ " has non trailing default value of '" + d.args()[nArgs].defaultValue() + "'. 
Only trailing arguments may have default values");
+            // Look for default values that aren't at the end and throw
+            while (--nArgs >= 0) {
+                if (d.args()[nArgs].defaultValue().length() > 0) {
+                    throw new IllegalStateException("Function " + 
value.getName() + " has non trailing default value of '" + 
d.args()[nArgs].defaultValue() + "'. Only trailing arguments may have default 
values");
+                }
             }
         }
     }
@@ -181,6 +190,11 @@ public class ParseNodeFactory {
         return info;
     }
 
+    public static Multimap<String, BuiltInFunctionInfo> 
getBuiltInFunctionMultimap(){
+        initBuiltInFunctionMap();
+        return BUILT_IN_FUNCTION_MULTIMAP;
+    }
+
     public ParseNodeFactory() {
     }
     

Reply via email to