[NO ISSUE][MTD] Remove '$' from function parameter names

- user model changes: no
- storage format changes: no
- interface changes: no

Details:
- Remove '$' prefix from parameter names in function metadata

Change-Id: Ic43990eb57360988034d425118bcfa03c71a0137
Reviewed-on: https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/4943
Contrib: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Tested-by: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Integration-Tests: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Reviewed-by: Ian Maxon <imaxon@uci.edu>
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/translator/QueryTranslator.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/translator/QueryTranslator.java
index 6e1db20..2998f7b 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/translator/QueryTranslator.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/translator/QueryTranslator.java
@@ -356,7 +356,7 @@
                         handleNodegroupDropStatement(metadataProvider, stmt);
                         break;
                     case CREATE_FUNCTION:
-                        handleCreateFunctionStatement(metadataProvider, stmt);
+                        handleCreateFunctionStatement(metadataProvider, stmt, stmtRewriter);
                         break;
                     case CREATE_ADAPTER:
                         handleCreateAdapterStatement(metadataProvider, stmt);
@@ -1761,7 +1761,8 @@
         }
     }
 
-    protected void handleCreateFunctionStatement(MetadataProvider metadataProvider, Statement stmt) throws Exception {
+    protected void handleCreateFunctionStatement(MetadataProvider metadataProvider, Statement stmt,
+            IStatementRewriter stmtRewriter) throws Exception {
         CreateFunctionStatement cfs = (CreateFunctionStatement) stmt;
         SourceLocation sourceLoc = cfs.getSourceLocation();
         FunctionSignature signature = cfs.getFunctionSignature();
@@ -1806,7 +1807,7 @@
                     }
                 }
                 paramVars.add(argVar);
-                argNames.add(argVar.getValue());
+                argNames.add(stmtRewriter.toFunctionParameterName(argVar));
                 argTypes.add(argType);
             }
 
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/external-library/udf_metadata/udf_metadata.3.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/external-library/udf_metadata/udf_metadata.3.adm
index e0d43e1..3b87226 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results/external-library/udf_metadata/udf_metadata.3.adm
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/external-library/udf_metadata/udf_metadata.3.adm
@@ -1,12 +1,12 @@
 { "fn": { "DataverseName": "externallibtest", "Name": "myfn001", "Arity": "0", "Params": [  ], "ReturnType": "any", "Definition": "org.apache.asterix.external.library.CapitalFinderFactory", "Language": "JAVA", "Kind": "SCALAR", "Dependencies": [ [  ], [  ], [  ] ], "ParamTypes": [  ], "Library": "testlib", "NullCall": false, "Deterministic": false } }
-{ "fn": { "DataverseName": "externallibtest", "Name": "myfn002", "Arity": "1", "Params": [ "$a" ], "ReturnType": "any", "Definition": "org.apache.asterix.external.library.CapitalFinderFactory", "Language": "JAVA", "Kind": "SCALAR", "Dependencies": [ [  ], [  ], [  ] ], "ParamTypes": [ { "Type": "any" } ], "Library": "testlib", "NullCall": false, "Deterministic": false } }
-{ "fn": { "DataverseName": "externallibtest", "Name": "myfn003", "Arity": "3", "Params": [ "$a", "$b", "$c" ], "ReturnType": "string", "Definition": "org.apache.asterix.external.library.CapitalFinderFactory", "Language": "JAVA", "Kind": "SCALAR", "Dependencies": [ [  ], [  ], [  ] ], "ReturnTypeIsNullable": false, "ParamTypes": [ { "Type": "string", "IsNullable": false }, { "Type": "fn$myfn003$3$1", "IsNullable": false }, { "Type": "fn$myfn003$3$2", "IsNullable": false } ], "Library": "testlib", "NullCall": false, "Deterministic": false } }
-{ "fn": { "DataverseName": "externallibtest", "Name": "myfn004", "Arity": "2", "Params": [ "$a", "$b" ], "ReturnType": "CountryCapitalType", "Definition": "org.apache.asterix.external.library.CapitalFinderFactory", "Language": "JAVA", "Kind": "SCALAR", "Dependencies": [ [  ], [  ], [ [ "externallibtest", "CountryCapitalType" ] ] ], "ReturnTypeIsNullable": false, "ParamTypes": [ { "Type": "CountryCapitalType", "IsNullable": false }, { "Type": "fn$myfn004$2$1", "IsNullable": false } ], "Library": "testlib", "NullCall": false, "Deterministic": false } }
-{ "fn": { "DataverseName": "externallibtest", "Name": "myfn005", "Arity": "4", "Params": [ "$a", "$b", "$c", "$d" ], "ReturnType": "string", "Definition": "org.apache.asterix.external.library.CapitalFinderFactory", "Language": "JAVA", "Kind": "SCALAR", "Dependencies": [ [  ], [  ], [ [ "externallibtest", "CountryCapitalType" ] ] ], "ReturnTypeIsNullable": true, "ParamTypes": [ { "Type": "string", "IsNullable": true }, { "Type": "fn$myfn005$4$1", "IsNullable": true }, { "Type": "CountryCapitalType", "IsNullable": true }, { "Type": "fn$myfn005$4$3", "IsNullable": true } ], "Library": "testlib", "NullCall": false, "Deterministic": false } }
-{ "fn": { "DataverseName": "externallibtest", "Name": "myfn006", "Arity": "1", "Params": [ "$a" ], "ReturnType": "fn$myfn006$1", "Definition": "org.apache.asterix.external.library.CapitalFinderFactory", "Language": "JAVA", "Kind": "SCALAR", "Dependencies": [ [  ], [  ], [  ] ], "ReturnTypeIsNullable": false, "ParamTypes": [ { "Type": "fn$myfn006$1$0", "IsNullable": false } ], "Library": "testlib", "NullCall": false, "Deterministic": false } }
-{ "fn": { "DataverseName": "externallibtest", "Name": "myfn007", "Arity": "1", "Params": [ "$a" ], "ReturnType": "fn$myfn007$1", "Definition": "org.apache.asterix.external.library.CapitalFinderFactory", "Language": "JAVA", "Kind": "SCALAR", "Dependencies": [ [  ], [  ], [  ] ], "ReturnTypeIsNullable": true, "ParamTypes": [ { "Type": "fn$myfn007$1$0", "IsNullable": true } ], "Library": "testlib", "NullCall": false, "Deterministic": false } }
-{ "fn": { "DataverseName": "externallibtest", "Name": "myfn008", "Arity": "1", "Params": [ "$a" ], "ReturnType": "fn$myfn008$1", "Definition": "org.apache.asterix.external.library.CapitalFinderFactory", "Language": "JAVA", "Kind": "SCALAR", "Dependencies": [ [  ], [  ], [ [ "externallibtest", "CountryCapitalType" ] ] ], "ReturnTypeIsNullable": false, "ParamTypes": [ { "Type": "fn$myfn008$1$0", "IsNullable": false } ], "Library": "testlib", "NullCall": false, "Deterministic": false } }
-{ "fn": { "DataverseName": "externallibtest", "Name": "myfn009", "Arity": "1", "Params": [ "$a" ], "ReturnType": "fn$myfn009$1", "Definition": "org.apache.asterix.external.library.CapitalFinderFactory", "Language": "JAVA", "Kind": "SCALAR", "Dependencies": [ [  ], [  ], [ [ "externallibtest", "CountryCapitalType" ] ] ], "ReturnTypeIsNullable": true, "ParamTypes": [ { "Type": "fn$myfn009$1$0", "IsNullable": true } ], "Library": "testlib", "NullCall": false, "Deterministic": false } }
+{ "fn": { "DataverseName": "externallibtest", "Name": "myfn002", "Arity": "1", "Params": [ "a" ], "ReturnType": "any", "Definition": "org.apache.asterix.external.library.CapitalFinderFactory", "Language": "JAVA", "Kind": "SCALAR", "Dependencies": [ [  ], [  ], [  ] ], "ParamTypes": [ { "Type": "any" } ], "Library": "testlib", "NullCall": false, "Deterministic": false } }
+{ "fn": { "DataverseName": "externallibtest", "Name": "myfn003", "Arity": "3", "Params": [ "a", "b", "c" ], "ReturnType": "string", "Definition": "org.apache.asterix.external.library.CapitalFinderFactory", "Language": "JAVA", "Kind": "SCALAR", "Dependencies": [ [  ], [  ], [  ] ], "ReturnTypeIsNullable": false, "ParamTypes": [ { "Type": "string", "IsNullable": false }, { "Type": "fn$myfn003$3$1", "IsNullable": false }, { "Type": "fn$myfn003$3$2", "IsNullable": false } ], "Library": "testlib", "NullCall": false, "Deterministic": false } }
+{ "fn": { "DataverseName": "externallibtest", "Name": "myfn004", "Arity": "2", "Params": [ "a", "b" ], "ReturnType": "CountryCapitalType", "Definition": "org.apache.asterix.external.library.CapitalFinderFactory", "Language": "JAVA", "Kind": "SCALAR", "Dependencies": [ [  ], [  ], [ [ "externallibtest", "CountryCapitalType" ] ] ], "ReturnTypeIsNullable": false, "ParamTypes": [ { "Type": "CountryCapitalType", "IsNullable": false }, { "Type": "fn$myfn004$2$1", "IsNullable": false } ], "Library": "testlib", "NullCall": false, "Deterministic": false } }
+{ "fn": { "DataverseName": "externallibtest", "Name": "myfn005", "Arity": "4", "Params": [ "a", "b", "c", "d" ], "ReturnType": "string", "Definition": "org.apache.asterix.external.library.CapitalFinderFactory", "Language": "JAVA", "Kind": "SCALAR", "Dependencies": [ [  ], [  ], [ [ "externallibtest", "CountryCapitalType" ] ] ], "ReturnTypeIsNullable": true, "ParamTypes": [ { "Type": "string", "IsNullable": true }, { "Type": "fn$myfn005$4$1", "IsNullable": true }, { "Type": "CountryCapitalType", "IsNullable": true }, { "Type": "fn$myfn005$4$3", "IsNullable": true } ], "Library": "testlib", "NullCall": false, "Deterministic": false } }
+{ "fn": { "DataverseName": "externallibtest", "Name": "myfn006", "Arity": "1", "Params": [ "a" ], "ReturnType": "fn$myfn006$1", "Definition": "org.apache.asterix.external.library.CapitalFinderFactory", "Language": "JAVA", "Kind": "SCALAR", "Dependencies": [ [  ], [  ], [  ] ], "ReturnTypeIsNullable": false, "ParamTypes": [ { "Type": "fn$myfn006$1$0", "IsNullable": false } ], "Library": "testlib", "NullCall": false, "Deterministic": false } }
+{ "fn": { "DataverseName": "externallibtest", "Name": "myfn007", "Arity": "1", "Params": [ "a" ], "ReturnType": "fn$myfn007$1", "Definition": "org.apache.asterix.external.library.CapitalFinderFactory", "Language": "JAVA", "Kind": "SCALAR", "Dependencies": [ [  ], [  ], [  ] ], "ReturnTypeIsNullable": true, "ParamTypes": [ { "Type": "fn$myfn007$1$0", "IsNullable": true } ], "Library": "testlib", "NullCall": false, "Deterministic": false } }
+{ "fn": { "DataverseName": "externallibtest", "Name": "myfn008", "Arity": "1", "Params": [ "a" ], "ReturnType": "fn$myfn008$1", "Definition": "org.apache.asterix.external.library.CapitalFinderFactory", "Language": "JAVA", "Kind": "SCALAR", "Dependencies": [ [  ], [  ], [ [ "externallibtest", "CountryCapitalType" ] ] ], "ReturnTypeIsNullable": false, "ParamTypes": [ { "Type": "fn$myfn008$1$0", "IsNullable": false } ], "Library": "testlib", "NullCall": false, "Deterministic": false } }
+{ "fn": { "DataverseName": "externallibtest", "Name": "myfn009", "Arity": "1", "Params": [ "a" ], "ReturnType": "fn$myfn009$1", "Definition": "org.apache.asterix.external.library.CapitalFinderFactory", "Language": "JAVA", "Kind": "SCALAR", "Dependencies": [ [  ], [  ], [ [ "externallibtest", "CountryCapitalType" ] ] ], "ReturnTypeIsNullable": true, "ParamTypes": [ { "Type": "fn$myfn009$1$0", "IsNullable": true } ], "Library": "testlib", "NullCall": false, "Deterministic": false } }
 { "dt": { "DataverseName": "externallibtest", "DatatypeName": "CountryCapitalType", "Derived": { "Tag": "RECORD", "IsAnonymous": false, "Record": { "IsOpen": false, "Fields": [ { "FieldName": "country", "FieldType": "string", "IsNullable": false }, { "FieldName": "capital", "FieldType": "string", "IsNullable": false } ] } } } }
 { "dt": { "DataverseName": "externallibtest", "DatatypeName": "fn$myfn003$3$1", "Derived": { "Tag": "ORDEREDLIST", "IsAnonymous": true, "OrderedList": "int64" } } }
 { "dt": { "DataverseName": "externallibtest", "DatatypeName": "fn$myfn003$3$2", "Derived": { "Tag": "UNORDEREDLIST", "IsAnonymous": true, "UnorderedList": "boolean" } } }
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/user-defined-functions/udf32_metadata/udf32_metadata.2.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/user-defined-functions/udf32_metadata/udf32_metadata.2.adm
index e181e6a..a6d1478 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results/user-defined-functions/udf32_metadata/udf32_metadata.2.adm
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/user-defined-functions/udf32_metadata/udf32_metadata.2.adm
@@ -1,12 +1,12 @@
 { "fn": { "DataverseName": "test", "Name": "myfn001", "Arity": "0", "Params": [  ], "ReturnType": "any", "Definition": "42", "Language": "SQLPP", "Kind": "SCALAR", "Dependencies": [ [  ], [  ], [  ] ], "ParamTypes": [  ] } }
-{ "fn": { "DataverseName": "test", "Name": "myfn002", "Arity": "1", "Params": [ "$a" ], "ReturnType": "any", "Definition": "a", "Language": "SQLPP", "Kind": "SCALAR", "Dependencies": [ [  ], [  ], [  ] ], "ParamTypes": [ { "Type": "any" } ] } }
-{ "fn": { "DataverseName": "test", "Name": "myfn003", "Arity": "3", "Params": [ "$a", "$b", "$c" ], "ReturnType": "string", "Definition": "a", "Language": "SQLPP", "Kind": "SCALAR", "Dependencies": [ [  ], [  ], [  ] ], "ReturnTypeIsNullable": false, "ParamTypes": [ { "Type": "string", "IsNullable": false }, { "Type": "fn$myfn003$3$1", "IsNullable": false }, { "Type": "fn$myfn003$3$2", "IsNullable": false } ] } }
-{ "fn": { "DataverseName": "test", "Name": "myfn004", "Arity": "2", "Params": [ "$a", "$b" ], "ReturnType": "MyType1", "Definition": "a", "Language": "SQLPP", "Kind": "SCALAR", "Dependencies": [ [  ], [  ], [ [ "test", "MyType1" ] ] ], "ReturnTypeIsNullable": false, "ParamTypes": [ { "Type": "MyType1", "IsNullable": false }, { "Type": "fn$myfn004$2$1", "IsNullable": false } ] } }
-{ "fn": { "DataverseName": "test", "Name": "myfn005", "Arity": "4", "Params": [ "$a", "$b", "$c", "$d" ], "ReturnType": "string", "Definition": "a", "Language": "SQLPP", "Kind": "SCALAR", "Dependencies": [ [  ], [  ], [ [ "test", "MyType1" ] ] ], "ReturnTypeIsNullable": true, "ParamTypes": [ { "Type": "string", "IsNullable": true }, { "Type": "fn$myfn005$4$1", "IsNullable": true }, { "Type": "MyType1", "IsNullable": true }, { "Type": "fn$myfn005$4$3", "IsNullable": true } ] } }
-{ "fn": { "DataverseName": "test", "Name": "myfn006", "Arity": "1", "Params": [ "$a" ], "ReturnType": "fn$myfn006$1", "Definition": "a", "Language": "SQLPP", "Kind": "SCALAR", "Dependencies": [ [  ], [  ], [  ] ], "ReturnTypeIsNullable": false, "ParamTypes": [ { "Type": "fn$myfn006$1$0", "IsNullable": false } ] } }
-{ "fn": { "DataverseName": "test", "Name": "myfn007", "Arity": "1", "Params": [ "$a" ], "ReturnType": "fn$myfn007$1", "Definition": "a", "Language": "SQLPP", "Kind": "SCALAR", "Dependencies": [ [  ], [  ], [  ] ], "ReturnTypeIsNullable": true, "ParamTypes": [ { "Type": "fn$myfn007$1$0", "IsNullable": true } ] } }
-{ "fn": { "DataverseName": "test", "Name": "myfn008", "Arity": "1", "Params": [ "$a" ], "ReturnType": "fn$myfn008$1", "Definition": "a", "Language": "SQLPP", "Kind": "SCALAR", "Dependencies": [ [  ], [  ], [ [ "test", "MyType1" ] ] ], "ReturnTypeIsNullable": false, "ParamTypes": [ { "Type": "fn$myfn008$1$0", "IsNullable": false } ] } }
-{ "fn": { "DataverseName": "test", "Name": "myfn009", "Arity": "1", "Params": [ "$a" ], "ReturnType": "fn$myfn009$1", "Definition": "a", "Language": "SQLPP", "Kind": "SCALAR", "Dependencies": [ [  ], [  ], [ [ "test", "MyType1" ] ] ], "ReturnTypeIsNullable": true, "ParamTypes": [ { "Type": "fn$myfn009$1$0", "IsNullable": true } ] } }
+{ "fn": { "DataverseName": "test", "Name": "myfn002", "Arity": "1", "Params": [ "a" ], "ReturnType": "any", "Definition": "a", "Language": "SQLPP", "Kind": "SCALAR", "Dependencies": [ [  ], [  ], [  ] ], "ParamTypes": [ { "Type": "any" } ] } }
+{ "fn": { "DataverseName": "test", "Name": "myfn003", "Arity": "3", "Params": [ "a", "b", "c" ], "ReturnType": "string", "Definition": "a", "Language": "SQLPP", "Kind": "SCALAR", "Dependencies": [ [  ], [  ], [  ] ], "ReturnTypeIsNullable": false, "ParamTypes": [ { "Type": "string", "IsNullable": false }, { "Type": "fn$myfn003$3$1", "IsNullable": false }, { "Type": "fn$myfn003$3$2", "IsNullable": false } ] } }
+{ "fn": { "DataverseName": "test", "Name": "myfn004", "Arity": "2", "Params": [ "a", "b" ], "ReturnType": "MyType1", "Definition": "a", "Language": "SQLPP", "Kind": "SCALAR", "Dependencies": [ [  ], [  ], [ [ "test", "MyType1" ] ] ], "ReturnTypeIsNullable": false, "ParamTypes": [ { "Type": "MyType1", "IsNullable": false }, { "Type": "fn$myfn004$2$1", "IsNullable": false } ] } }
+{ "fn": { "DataverseName": "test", "Name": "myfn005", "Arity": "4", "Params": [ "a", "b", "c", "d" ], "ReturnType": "string", "Definition": "a", "Language": "SQLPP", "Kind": "SCALAR", "Dependencies": [ [  ], [  ], [ [ "test", "MyType1" ] ] ], "ReturnTypeIsNullable": true, "ParamTypes": [ { "Type": "string", "IsNullable": true }, { "Type": "fn$myfn005$4$1", "IsNullable": true }, { "Type": "MyType1", "IsNullable": true }, { "Type": "fn$myfn005$4$3", "IsNullable": true } ] } }
+{ "fn": { "DataverseName": "test", "Name": "myfn006", "Arity": "1", "Params": [ "a" ], "ReturnType": "fn$myfn006$1", "Definition": "a", "Language": "SQLPP", "Kind": "SCALAR", "Dependencies": [ [  ], [  ], [  ] ], "ReturnTypeIsNullable": false, "ParamTypes": [ { "Type": "fn$myfn006$1$0", "IsNullable": false } ] } }
+{ "fn": { "DataverseName": "test", "Name": "myfn007", "Arity": "1", "Params": [ "a" ], "ReturnType": "fn$myfn007$1", "Definition": "a", "Language": "SQLPP", "Kind": "SCALAR", "Dependencies": [ [  ], [  ], [  ] ], "ReturnTypeIsNullable": true, "ParamTypes": [ { "Type": "fn$myfn007$1$0", "IsNullable": true } ] } }
+{ "fn": { "DataverseName": "test", "Name": "myfn008", "Arity": "1", "Params": [ "a" ], "ReturnType": "fn$myfn008$1", "Definition": "a", "Language": "SQLPP", "Kind": "SCALAR", "Dependencies": [ [  ], [  ], [ [ "test", "MyType1" ] ] ], "ReturnTypeIsNullable": false, "ParamTypes": [ { "Type": "fn$myfn008$1$0", "IsNullable": false } ] } }
+{ "fn": { "DataverseName": "test", "Name": "myfn009", "Arity": "1", "Params": [ "a" ], "ReturnType": "fn$myfn009$1", "Definition": "a", "Language": "SQLPP", "Kind": "SCALAR", "Dependencies": [ [  ], [  ], [ [ "test", "MyType1" ] ] ], "ReturnTypeIsNullable": true, "ParamTypes": [ { "Type": "fn$myfn009$1$0", "IsNullable": true } ] } }
 { "dt": { "DataverseName": "test", "DatatypeName": "MyType1", "Derived": { "Tag": "RECORD", "IsAnonymous": false, "Record": { "IsOpen": true, "Fields": [ { "FieldName": "id", "FieldType": "int64", "IsNullable": false }, { "FieldName": "value", "FieldType": "string", "IsNullable": false } ] } } } }
 { "dt": { "DataverseName": "test", "DatatypeName": "fn$myfn003$3$1", "Derived": { "Tag": "ORDEREDLIST", "IsAnonymous": true, "OrderedList": "int64" } } }
 { "dt": { "DataverseName": "test", "DatatypeName": "fn$myfn003$3$2", "Derived": { "Tag": "UNORDEREDLIST", "IsAnonymous": true, "UnorderedList": "boolean" } } }
diff --git a/asterixdb/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/rewrites/AqlStatementRewriter.java b/asterixdb/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/rewrites/AqlStatementRewriter.java
index 6c4b178..eee6499 100644
--- a/asterixdb/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/rewrites/AqlStatementRewriter.java
+++ b/asterixdb/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/rewrites/AqlStatementRewriter.java
@@ -22,10 +22,13 @@
 import org.apache.asterix.lang.aql.visitor.AqlStatementRewriteVisitor;
 import org.apache.asterix.lang.common.base.IStatementRewriter;
 import org.apache.asterix.lang.common.base.Statement;
+import org.apache.asterix.lang.common.struct.VarIdentifier;
 import org.apache.asterix.metadata.declared.MetadataProvider;
 
 class AqlStatementRewriter implements IStatementRewriter {
 
+    private static final char VAR_PREFIX = '$';
+
     @Override
     public boolean isRewritable(Statement.Kind kind) {
         return kind == Statement.Kind.DELETE;
@@ -42,4 +45,13 @@
     public String toExternalVariableName(String statementParameterName) {
         return null;
     }
+
+    @Override
+    public String toFunctionParameterName(VarIdentifier paramVar) {
+        String name = paramVar.getValue();
+        if (name.charAt(0) != VAR_PREFIX) {
+            throw new IllegalArgumentException(name);
+        }
+        return name.substring(1);
+    }
 }
diff --git a/asterixdb/asterix-lang-aql/src/main/javacc/AQL.jj b/asterixdb/asterix-lang-aql/src/main/javacc/AQL.jj
index c73a1e8..a5ffe03 100644
--- a/asterixdb/asterix-lang-aql/src/main/javacc/AQL.jj
+++ b/asterixdb/asterix-lang-aql/src/main/javacc/AQL.jj
@@ -189,6 +189,8 @@
 
     private static final String INT_TYPE_NAME = "int";
 
+    private static final char VAR_PREFIX = '$';
+
     private DataverseName defaultDataverse;
 
     private static class IndexParams {
@@ -311,21 +313,24 @@
     }
 
     @Override
-    public Expression parseFunctionBody(FunctionSignature signature, List<VarIdentifier> paramList)
+    public FunctionDecl parseFunctionBody(FunctionSignature signature, List<String> paramNames)
       throws CompilationException {
-        return parseImpl(new ParseFunction<Expression>() {
+        return parseImpl(new ParseFunction<FunctionDecl>() {
             @Override
-            public Expression parse() throws ParseException {
+            public FunctionDecl parse() throws ParseException {
                 DataverseName dataverse = defaultDataverse;
                 defaultDataverse = signature.getDataverseName();
                 createNewScope();
-                for (VarIdentifier var : paramList) {
-                  getCurrentScope().addNewVarSymbolToScope(var);
+                List<VarIdentifier> paramVars = new ArrayList<VarIdentifier>(paramNames.size());
+                for (String paramName : paramNames) {
+                    VarIdentifier var = new VarIdentifier(VAR_PREFIX + paramName);
+                    paramVars.add(var);
+                    getCurrentScope().addNewVarSymbolToScope(var);
                 }
                 Expression functionBodyExpr = AQLParser.this.FunctionBody();
                 removeCurrentScope();
                 defaultDataverse = dataverse;
-                return functionBodyExpr;
+                return new FunctionDecl(signature, paramVars, functionBodyExpr);
             }
         });
     }
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/base/IParser.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/base/IParser.java
index 578d954..3f73789 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/base/IParser.java
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/base/IParser.java
@@ -23,15 +23,14 @@
 
 import org.apache.asterix.common.exceptions.CompilationException;
 import org.apache.asterix.common.functions.FunctionSignature;
-import org.apache.asterix.lang.common.struct.VarIdentifier;
+import org.apache.asterix.lang.common.statement.FunctionDecl;
 import org.apache.hyracks.api.exceptions.Warning;
 
 public interface IParser {
 
     List<Statement> parse() throws CompilationException;
 
-    Expression parseFunctionBody(FunctionSignature signature, List<VarIdentifier> paramList)
-            throws CompilationException;
+    FunctionDecl parseFunctionBody(FunctionSignature signature, List<String> paramNames) throws CompilationException;
 
     /**
      * Gets the warnings generated during parsing up to the max number argument.
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/base/IStatementRewriter.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/base/IStatementRewriter.java
index 8d5b374..9d983b0 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/base/IStatementRewriter.java
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/base/IStatementRewriter.java
@@ -19,6 +19,7 @@
 package org.apache.asterix.lang.common.base;
 
 import org.apache.asterix.common.exceptions.CompilationException;
+import org.apache.asterix.lang.common.struct.VarIdentifier;
 import org.apache.asterix.metadata.declared.MetadataProvider;
 
 public interface IStatementRewriter {
@@ -37,4 +38,6 @@
     void rewrite(Statement statement, MetadataProvider metadataProvider) throws CompilationException;
 
     String toExternalVariableName(String statementParameterName);
+
+    String toFunctionParameterName(VarIdentifier paramVar);
 }
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/parser/FunctionParser.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/parser/FunctionParser.java
index 2e8754c..2a717a9 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/parser/FunctionParser.java
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/parser/FunctionParser.java
@@ -20,17 +20,12 @@
 package org.apache.asterix.lang.common.parser;
 
 import java.io.StringReader;
-import java.util.ArrayList;
-import java.util.List;
 
 import org.apache.asterix.common.exceptions.CompilationException;
 import org.apache.asterix.common.exceptions.ErrorCode;
-import org.apache.asterix.common.functions.FunctionSignature;
-import org.apache.asterix.lang.common.base.Expression;
 import org.apache.asterix.lang.common.base.IParser;
 import org.apache.asterix.lang.common.base.IParserFactory;
 import org.apache.asterix.lang.common.statement.FunctionDecl;
-import org.apache.asterix.lang.common.struct.VarIdentifier;
 import org.apache.asterix.metadata.entities.Function;
 
 public class FunctionParser {
@@ -46,22 +41,10 @@
 
     public FunctionDecl getFunctionDecl(Function function) throws CompilationException {
         if (!function.getLanguage().equals(language)) {
-            throw new CompilationException(ErrorCode.COMPILATION_INCOMPATIBLE_FUNCTION_LANGUAGE, language,
-                    function.getLanguage());
+            throw new CompilationException(ErrorCode.COMPILATION_INCOMPATIBLE_FUNCTION_LANGUAGE, language.getName(),
+                    function.getLanguage().getName());
         }
-
-        FunctionSignature signature = function.getSignature();
-
-        List<String> argNames = function.getArgNames();
-        List<VarIdentifier> paramList = new ArrayList<>(argNames.size());
-        for (String argName : argNames) {
-            paramList.add(new VarIdentifier(argName));
-        }
-
-        String functionBody = function.getFunctionBody();
-        IParser parser = parserFactory.createParser(new StringReader(functionBody));
-        Expression functionBodyExpr = parser.parseFunctionBody(signature, paramList);
-
-        return new FunctionDecl(signature, paramList, functionBodyExpr);
+        IParser parser = parserFactory.createParser(new StringReader(function.getFunctionBody()));
+        return parser.parseFunctionBody(function.getSignature(), function.getArgNames());
     }
 }
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/SqlppStatementRewriter.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/SqlppStatementRewriter.java
index 566b313..a9caacb 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/SqlppStatementRewriter.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/SqlppStatementRewriter.java
@@ -21,6 +21,7 @@
 import org.apache.asterix.common.exceptions.CompilationException;
 import org.apache.asterix.lang.common.base.IStatementRewriter;
 import org.apache.asterix.lang.common.base.Statement;
+import org.apache.asterix.lang.common.struct.VarIdentifier;
 import org.apache.asterix.lang.sqlpp.util.SqlppVariableUtil;
 import org.apache.asterix.lang.sqlpp.visitor.SqlppDeleteRewriteVisitor;
 import org.apache.asterix.lang.sqlpp.visitor.SqlppSynonymRewriteVisitor;
@@ -53,4 +54,9 @@
     public String toExternalVariableName(String statementParameterName) {
         return SqlppVariableUtil.toExternalVariableName(statementParameterName);
     }
+
+    @Override
+    public String toFunctionParameterName(VarIdentifier paramVar) {
+        return SqlppVariableUtil.toUserDefinedName(paramVar.getValue());
+    }
 }
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj b/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj
index feff5c5..768de7e 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj
+++ b/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj
@@ -349,18 +349,22 @@
     }
 
     @Override
-    public Expression parseFunctionBody(FunctionSignature signature, List<VarIdentifier> paramList)
+    public FunctionDecl parseFunctionBody(FunctionSignature signature, List<String> paramNames)
       throws CompilationException {
-        return parseImpl(new ParseFunction<Expression>() {
+        return parseImpl(new ParseFunction<FunctionDecl>() {
             @Override
-            public Expression parse() throws ParseException {
+            public FunctionDecl parse() throws ParseException {
                 DataverseName dataverse = defaultDataverse;
                 defaultDataverse = signature.getDataverseName();
                 createNewScope();
+                List<VarIdentifier> paramVars = new ArrayList<VarIdentifier>(paramNames.size());
+                for (String paramName : paramNames) {
+                    paramVars.add(SqlppVariableUtil.toInternalVariableIdentifier(paramName));
+                }
                 Expression functionBodyExpr = SQLPPParser.this.FunctionBody();
                 removeCurrentScope();
                 defaultDataverse = dataverse;
-                return functionBodyExpr;
+                return new FunctionDecl(signature, paramVars, functionBodyExpr);
             }
         });
     }