[NO ISSUE]: Introduction of BUILT_IN_FUNCTION entity

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

Details:
- Refactor newFunction to consistently take function signature
- Add built-in functions to accessed entity

Ext-ref: MB-65507

Change-Id: Icf7d0ccef632cf4d95f215b9c0f24ae6fe9d5878
Reviewed-on: https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/19490
Integration-Tests: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Tested-by: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Reviewed-by: Janhavi Tripurwar <janhavi.tripurwar@couchbase.com>
Reviewed-by: Ali Alsuliman <ali.al.solaiman@gmail.com>
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 c8885dc..663876f 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
@@ -3400,8 +3400,8 @@
                 }
                 MetadataManager.INSTANCE.updateFunction(mdTxnCtx, function);
             }
-            beforeTxnCommit(metadataProvider, creator,
-                    EntityDetails.newFunction(databaseName, dataverseName, function.getName(), function.getArity()));
+
+            beforeTxnCommit(metadataProvider, creator, EntityDetails.newFunction(functionSignature));
             MetadataManager.INSTANCE.commitTransaction(mdTxnCtx);
             if (LOGGER.isInfoEnabled()) {
                 LOGGER.info("Installed function: " + functionSignature);
diff --git a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/functions/FunctionSignature.java b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/functions/FunctionSignature.java
index 890890c..857482b 100644
--- a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/functions/FunctionSignature.java
+++ b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/functions/FunctionSignature.java
@@ -139,7 +139,7 @@
         return createFunctionIdentifier(databaseName, dataverseName, name, arity);
     }
 
-    private static FunctionIdentifier createFunctionIdentifier(String databaseName, DataverseName dataverseName,
+    public static FunctionIdentifier createFunctionIdentifier(String databaseName, DataverseName dataverseName,
             String functionName, int arity) {
         return new FunctionIdentifier(databaseName, dataverseName.getCanonicalForm(), functionName, arity);
     }
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/util/ExpressionUtils.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/util/ExpressionUtils.java
index df7d6d8..a7de541 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/util/ExpressionUtils.java
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/util/ExpressionUtils.java
@@ -291,16 +291,17 @@
                                             datasetReference.getDatasetName(), null));
                                 }
                             }
+                        } else {
+                            addFunctionAccessedEntity(metadataProvider, signature);
                         }
                     } else {
                         if (seenFunctions.add(signature)) {
-                            String functionName = signature.getName() + "(" + signature.getArity() + ")";
-                            metadataProvider.addAccessedEntity(EntityDetails.newFunction(signature.getDatabaseName(),
-                                    signature.getDataverseName(), functionName, signature.getArity()));
+                            addFunctionAccessedEntity(metadataProvider, signature);
                             outFunctionDependencies.add(new DependencyFullyQualifiedName(signature.getDatabaseName(),
                                     signature.getDataverseName(), signature.getName(),
                                     Integer.toString(signature.getArity())));
                         }
+
                     }
                     break;
                 case WINDOW_EXPRESSION:
@@ -313,6 +314,10 @@
         }
     }
 
+    private static void addFunctionAccessedEntity(MetadataProvider metadataProvider, FunctionSignature signature) {
+        metadataProvider.addAccessedEntity(EntityDetails.newFunction(signature));
+    }
+
     public static boolean hasFunctionOrViewRecursion(Map<FunctionSignature, FunctionDecl> functionDeclMap,
             Map<DatasetFullyQualifiedName, ViewDecl> viewDeclMap,
             java.util.function.Function<Collection<AbstractCallExpression>, GatherFunctionCallsVisitor> callVisitorFactory)
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppLoadAccessedDataset.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppLoadAccessedDataset.java
index 1b1cf83..986c3d1 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppLoadAccessedDataset.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppLoadAccessedDataset.java
@@ -98,9 +98,7 @@
             if (declaredFunctions.containsKey(signature)) {
                 return;
             }
-            String functionName = EntityDetails.getFunctionNameWithArity(signature.getName(), signature.getArity());
-            context.getMetadataProvider().addAccessedEntity(EntityDetails.newFunction(signature.getDatabaseName(),
-                    signature.getDataverseName(), functionName, signature.getArity()));
+            context.getMetadataProvider().addAccessedEntity(EntityDetails.newFunction(signature));
         }
     }
 }
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/EntityDetails.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/EntityDetails.java
index c7e771b..068fb20 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/EntityDetails.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/EntityDetails.java
@@ -18,7 +18,12 @@
  */
 package org.apache.asterix.metadata.entities;
 
+import java.util.Objects;
+
+import org.apache.asterix.common.functions.FunctionConstants;
+import org.apache.asterix.common.functions.FunctionSignature;
 import org.apache.asterix.common.metadata.DataverseName;
+import org.apache.asterix.om.functions.BuiltinFunctions;
 
 /**
  * This class provides static factory methods for creating entity details.
@@ -33,7 +38,8 @@
         DATABASE,
         DATAVERSE,
         SYNONYM,
-        INDEX
+        INDEX,
+        BUILT_IN_FUNCTION;
     }
 
     private final String databaseName;
@@ -75,9 +81,19 @@
         return new EntityDetails(databaseName, dataverseName, viewName, EntityType.VIEW);
     }
 
-    public static EntityDetails newFunction(String databaseName, DataverseName dataverseName, String functionName,
-            int functionArity) {
-        return new EntityDetails(databaseName, dataverseName, functionName, EntityType.FUNCTION, functionArity);
+    public static EntityDetails newFunction(FunctionSignature fs) {
+        boolean isBuiltInFunc = isBuiltinFunctionSignature(fs);
+        String databaseName = fs.getDatabaseName();
+        String functionName = fs.getName();
+        Integer functionArity = fs.getArity();
+        DataverseName dataverseName = fs.getDataverseName();
+        String functionNameWithArity = getFunctionNameWithArity(functionName, functionArity);
+        if (isBuiltInFunc) {
+            return new EntityDetails(databaseName, dataverseName, functionNameWithArity, EntityType.BUILT_IN_FUNCTION,
+                    functionArity);
+        }
+        return new EntityDetails(databaseName, dataverseName, functionNameWithArity, EntityType.FUNCTION,
+                functionArity);
     }
 
     public static EntityDetails newSynonym(String databaseName, DataverseName dataverseName, String synonymName) {
@@ -112,7 +128,24 @@
         return functionArity;
     }
 
+    public static boolean isBuiltinFunctionSignature(FunctionSignature fs) {
+        return isBuiltinFunctionDataverse(Objects.requireNonNull(fs.getDataverseName()))
+                || BuiltinFunctions.getBuiltinFunctionInfo(fs.createFunctionIdentifier()) != null;
+    }
+
+    private static boolean isBuiltinFunctionDataverse(DataverseName dataverse) {
+        return FunctionConstants.ASTERIX_DV.equals(dataverse) || FunctionConstants.ALGEBRICKS_DV.equals(dataverse);
+    }
+
     public static String getFunctionNameWithArity(String functionName, int functionArity) {
         return functionName + "(" + functionArity + ")";
     }
+
+    public static String getFunctionNameWithoutArity(String functionNameWithArity) {
+        int index = functionNameWithArity.indexOf('(');
+        if (index != -1) {
+            return functionNameWithArity.substring(0, index);
+        }
+        return functionNameWithArity;
+    }
 }