Search in sources :

Example 6 with FunctionDecl

use of org.apache.asterix.lang.common.statement.FunctionDecl in project asterixdb by apache.

the class FunctionUtil method retrieveUsedStoredFunctions.

/**
     * Retrieve stored functions (from CREATE FUNCTION statements) that have been used in an expression.
     *
     * @param metadataProvider,
     *            the metadata provider
     * @param expression,
     *            the expression for analysis
     * @param declaredFunctions,
     *            a set of declared functions in the query, which can potentially override stored functions.
     * @param functionCollector,
     *            for collecting function calls in the <code>expression</code>
     * @param functionParser,
     *            for parsing stored functions in the string represetnation.
     * @param functionNormalizer,
     *            for normalizing function names.
     * @throws CompilationException
     */
public static List<FunctionDecl> retrieveUsedStoredFunctions(MetadataProvider metadataProvider, Expression expression, List<FunctionSignature> declaredFunctions, List<FunctionDecl> inputFunctionDecls, IFunctionCollector functionCollector, IFunctionParser functionParser, IFunctionNormalizer functionNormalizer) throws CompilationException {
    List<FunctionDecl> functionDecls = inputFunctionDecls == null ? new ArrayList<>() : new ArrayList<>(inputFunctionDecls);
    if (expression == null) {
        return functionDecls;
    }
    String value = metadataProvider.getConfig().get(FunctionUtil.IMPORT_PRIVATE_FUNCTIONS);
    boolean includePrivateFunctions = (value != null) ? Boolean.valueOf(value.toLowerCase()) : false;
    Set<FunctionSignature> functionCalls = functionCollector.getFunctionCalls(expression);
    for (FunctionSignature signature : functionCalls) {
        if (declaredFunctions != null && declaredFunctions.contains(signature)) {
            continue;
        }
        if (signature.getNamespace() == null) {
            signature.setNamespace(metadataProvider.getDefaultDataverseName());
        }
        String namespace = signature.getNamespace();
        // Checks the existence of the referred dataverse.
        if (metadataProvider.findDataverse(namespace) == null && !namespace.equals(FunctionConstants.ASTERIX_NS)) {
            throw new CompilationException("In function call \"" + namespace + "." + signature.getName() + "(...)\", the dataverse \"" + namespace + "\" cannot be found!");
        }
        Function function = lookupUserDefinedFunctionDecl(metadataProvider.getMetadataTxnContext(), signature);
        if (function == null) {
            FunctionSignature normalizedSignature = functionNormalizer == null ? signature : functionNormalizer.normalizeBuiltinFunctionSignature(signature);
            if (BuiltinFunctions.isBuiltinCompilerFunction(normalizedSignature, includePrivateFunctions)) {
                continue;
            }
            StringBuilder messageBuilder = new StringBuilder();
            if (!functionDecls.isEmpty()) {
                messageBuilder.append("function " + functionDecls.get(functionDecls.size() - 1).getSignature() + " depends upon function " + signature + " which is undefined");
            } else {
                messageBuilder.append("function " + signature + " is not defined");
            }
            throw new CompilationException(messageBuilder.toString());
        }
        if (function.getLanguage().equalsIgnoreCase(Function.LANGUAGE_AQL)) {
            FunctionDecl functionDecl = functionParser.getFunctionDecl(function);
            if (functionDecl != null) {
                if (functionDecls.contains(functionDecl)) {
                    throw new CompilationException("Recursive invocation " + functionDecls.get(functionDecls.size() - 1).getSignature() + " <==> " + functionDecl.getSignature());
                }
                functionDecls.add(functionDecl);
                functionDecls = retrieveUsedStoredFunctions(metadataProvider, functionDecl.getFuncBody(), declaredFunctions, functionDecls, functionCollector, functionParser, functionNormalizer);
            }
        }
    }
    return functionDecls;
}
Also used : CompilationException(org.apache.asterix.common.exceptions.CompilationException) Function(org.apache.asterix.metadata.entities.Function) FunctionSignature(org.apache.asterix.common.functions.FunctionSignature) FunctionDecl(org.apache.asterix.lang.common.statement.FunctionDecl)

Example 7 with FunctionDecl

use of org.apache.asterix.lang.common.statement.FunctionDecl in project asterixdb by apache.

the class AqlQueryRewriter method inlineDeclaredUdfs.

private void inlineDeclaredUdfs() throws CompilationException {
    if (topStatement == null) {
        return;
    }
    List<FunctionSignature> funIds = new ArrayList<FunctionSignature>();
    for (FunctionDecl fdecl : declaredFunctions) {
        funIds.add(fdecl.getSignature());
    }
    List<FunctionDecl> storedFunctionDecls = new ArrayList<>();
    for (Expression topLevelExpr : topStatement.getDirectlyEnclosedExpressions()) {
        storedFunctionDecls.addAll(FunctionUtil.retrieveUsedStoredFunctions(metadataProvider, topLevelExpr, funIds, null, expr -> getFunctionCalls(expr), func -> functionParser.getFunctionDecl(func), signature -> CommonFunctionMapUtil.normalizeBuiltinFunctionSignature(signature)));
        declaredFunctions.addAll(storedFunctionDecls);
    }
    if (!declaredFunctions.isEmpty()) {
        AQLInlineUdfsVisitor visitor = new AQLInlineUdfsVisitor(context, new AQLRewriterFactory(), declaredFunctions, metadataProvider);
        while (topStatement.accept(visitor, declaredFunctions)) {
        // loop until no more changes
        }
    }
    declaredFunctions.removeAll(storedFunctionDecls);
}
Also used : IAQLVisitor(org.apache.asterix.lang.aql.visitor.base.IAQLVisitor) ForClause(org.apache.asterix.lang.aql.clause.ForClause) DistinctClause(org.apache.asterix.lang.aql.clause.DistinctClause) ArrayList(java.util.ArrayList) GroupbyClause(org.apache.asterix.lang.common.clause.GroupbyClause) IReturningStatement(org.apache.asterix.lang.common.base.IReturningStatement) FunctionUtil(org.apache.asterix.lang.common.util.FunctionUtil) LetClause(org.apache.asterix.lang.common.clause.LetClause) FunctionSignature(org.apache.asterix.common.functions.FunctionSignature) FLWOGRExpression(org.apache.asterix.lang.aql.expression.FLWOGRExpression) Kind(org.apache.asterix.lang.common.base.Expression.Kind) FunctionDecl(org.apache.asterix.lang.common.statement.FunctionDecl) CompilationException(org.apache.asterix.common.exceptions.CompilationException) AQLParserFactory(org.apache.asterix.lang.aql.parser.AQLParserFactory) Clause(org.apache.asterix.lang.common.base.Clause) Expression(org.apache.asterix.lang.common.base.Expression) Set(java.util.Set) LangRewritingContext(org.apache.asterix.lang.common.rewrites.LangRewritingContext) VarIdentifier(org.apache.asterix.lang.common.struct.VarIdentifier) CommonFunctionMapUtil(org.apache.asterix.lang.common.util.CommonFunctionMapUtil) IQueryRewriter(org.apache.asterix.lang.common.base.IQueryRewriter) GatherFunctionCallsVisitor(org.apache.asterix.lang.common.visitor.GatherFunctionCallsVisitor) VariableExpr(org.apache.asterix.lang.common.expression.VariableExpr) List(java.util.List) GbyVariableExpressionPair(org.apache.asterix.lang.common.expression.GbyVariableExpressionPair) MetadataProvider(org.apache.asterix.metadata.declared.MetadataProvider) AqlBuiltinFunctionRewriteVisitor(org.apache.asterix.lang.aql.rewrites.visitor.AqlBuiltinFunctionRewriteVisitor) AQLInlineUdfsVisitor(org.apache.asterix.lang.aql.visitor.AQLInlineUdfsVisitor) UnionExpr(org.apache.asterix.lang.aql.expression.UnionExpr) FunctionParser(org.apache.asterix.lang.aql.parser.FunctionParser) AQLInlineUdfsVisitor(org.apache.asterix.lang.aql.visitor.AQLInlineUdfsVisitor) FLWOGRExpression(org.apache.asterix.lang.aql.expression.FLWOGRExpression) Expression(org.apache.asterix.lang.common.base.Expression) ArrayList(java.util.ArrayList) FunctionSignature(org.apache.asterix.common.functions.FunctionSignature) FunctionDecl(org.apache.asterix.lang.common.statement.FunctionDecl)

Example 8 with FunctionDecl

use of org.apache.asterix.lang.common.statement.FunctionDecl in project asterixdb by apache.

the class ParserTestExecutor method testSQLPPParser.

// Tests the SQL++ parser.
public void testSQLPPParser(File queryFile, File actualResultFile, File expectedFile) throws Exception {
    actualResultFile.getParentFile().mkdirs();
    PrintWriter writer = new PrintWriter(new FileOutputStream(actualResultFile));
    IParser parser = sqlppParserFactory.createParser(readTestFile(queryFile));
    GlobalConfig.ASTERIX_LOGGER.info(queryFile.toString());
    try {
        List<Statement> statements = parser.parse();
        List<FunctionDecl> functions = getDeclaredFunctions(statements);
        String dvName = getDefaultDataverse(statements);
        MetadataProvider metadataProvider = mock(MetadataProvider.class);
        @SuppressWarnings("unchecked") Map<String, String> config = mock(Map.class);
        when(metadataProvider.getDefaultDataverseName()).thenReturn(dvName);
        when(metadataProvider.getConfig()).thenReturn(config);
        when(config.get(FunctionUtil.IMPORT_PRIVATE_FUNCTIONS)).thenReturn("true");
        when(metadataProvider.findDataset(anyString(), anyString())).thenReturn(mock(Dataset.class));
        for (Statement st : statements) {
            if (st.getKind() == Statement.Kind.QUERY) {
                Query query = (Query) st;
                IQueryRewriter rewriter = sqlppRewriterFactory.createQueryRewriter();
                rewrite(rewriter, functions, query, metadataProvider, new LangRewritingContext(query.getVarCounter()));
                // Tests deep copy and deep equality.
                Query copiedQuery = (Query) SqlppRewriteUtil.deepCopy(query);
                Assert.assertEquals(query.hashCode(), copiedQuery.hashCode());
                Assert.assertEquals(query, copiedQuery);
            }
            SqlppAstPrintUtil.print(st, writer);
        }
        writer.close();
        // Compares the actual result and the expected result.
        runScriptAndCompareWithResult(queryFile, new PrintWriter(System.err), expectedFile, actualResultFile, ComparisonEnum.TEXT);
    } catch (Exception e) {
        GlobalConfig.ASTERIX_LOGGER.warning("Failed while testing file " + queryFile);
        throw e;
    } finally {
        writer.close();
    }
}
Also used : Query(org.apache.asterix.lang.common.statement.Query) Statement(org.apache.asterix.lang.common.base.Statement) Dataset(org.apache.asterix.metadata.entities.Dataset) Matchers.anyString(org.mockito.Matchers.anyString) IQueryRewriter(org.apache.asterix.lang.common.base.IQueryRewriter) ComparisonException(org.apache.asterix.test.common.ComparisonException) AsterixException(org.apache.asterix.common.exceptions.AsterixException) FunctionDecl(org.apache.asterix.lang.common.statement.FunctionDecl) MetadataProvider(org.apache.asterix.metadata.declared.MetadataProvider) FileOutputStream(java.io.FileOutputStream) PrintWriter(java.io.PrintWriter) IParser(org.apache.asterix.lang.common.base.IParser) LangRewritingContext(org.apache.asterix.lang.common.rewrites.LangRewritingContext)

Aggregations

FunctionDecl (org.apache.asterix.lang.common.statement.FunctionDecl)8 ArrayList (java.util.ArrayList)5 VarIdentifier (org.apache.asterix.lang.common.struct.VarIdentifier)5 CompilationException (org.apache.asterix.common.exceptions.CompilationException)4 Expression (org.apache.asterix.lang.common.base.Expression)4 FunctionSignature (org.apache.asterix.common.functions.FunctionSignature)3 IParser (org.apache.asterix.lang.common.base.IParser)3 IQueryRewriter (org.apache.asterix.lang.common.base.IQueryRewriter)3 Statement (org.apache.asterix.lang.common.base.Statement)3 LetClause (org.apache.asterix.lang.common.clause.LetClause)3 GbyVariableExpressionPair (org.apache.asterix.lang.common.expression.GbyVariableExpressionPair)3 VariableExpr (org.apache.asterix.lang.common.expression.VariableExpr)3 LangRewritingContext (org.apache.asterix.lang.common.rewrites.LangRewritingContext)3 List (java.util.List)2 Set (java.util.Set)2 ILangExpression (org.apache.asterix.lang.common.base.ILangExpression)2 IReturningStatement (org.apache.asterix.lang.common.base.IReturningStatement)2 QuantifiedExpression (org.apache.asterix.lang.common.expression.QuantifiedExpression)2 VariableSubstitutionEnvironment (org.apache.asterix.lang.common.rewrites.VariableSubstitutionEnvironment)2 QuantifiedPair (org.apache.asterix.lang.common.struct.QuantifiedPair)2