Search in sources :

Example 1 with FunctionDecl

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

the class FunctionParser method getFunctionDecl.

public FunctionDecl getFunctionDecl(Function function) throws CompilationException {
    String functionBody = function.getFunctionBody();
    List<String> params = function.getParams();
    List<VarIdentifier> varIdentifiers = new ArrayList<VarIdentifier>();
    StringBuilder builder = new StringBuilder();
    builder.append(" use dataverse " + function.getDataverseName() + ";");
    builder.append(" declare function " + function.getName().split("@")[0]);
    builder.append("(");
    boolean first = true;
    for (String param : params) {
        VarIdentifier varId = new VarIdentifier(param);
        varIdentifiers.add(varId);
        if (first) {
            first = false;
        } else {
            builder.append(",");
        }
        builder.append(param);
    }
    builder.append("){\n").append(functionBody).append("\n}");
    IParser parser = parserFactory.createParser(new CharSequenceReader(builder));
    List<Statement> statements = parser.parse();
    FunctionDecl decl = (FunctionDecl) statements.get(1);
    return decl;
}
Also used : CharSequenceReader(org.apache.commons.io.input.CharSequenceReader) VarIdentifier(org.apache.asterix.lang.common.struct.VarIdentifier) Statement(org.apache.asterix.lang.common.base.Statement) ArrayList(java.util.ArrayList) IParser(org.apache.asterix.lang.common.base.IParser) FunctionDecl(org.apache.asterix.lang.common.statement.FunctionDecl)

Example 2 with FunctionDecl

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

the class AbstractInlineUdfsVisitor method inlineUdfsInExpr.

protected Pair<Boolean, Expression> inlineUdfsInExpr(Expression expr, List<FunctionDecl> arg) throws CompilationException {
    if (expr.getKind() != Kind.CALL_EXPRESSION) {
        boolean r = expr.accept(this, arg);
        return new Pair<>(r, expr);
    }
    CallExpr f = (CallExpr) expr;
    boolean r = expr.accept(this, arg);
    FunctionDecl implem = findFuncDeclaration(f.getFunctionSignature(), arg);
    if (implem == null) {
        return new Pair<>(r, expr);
    } else {
        // Rewrite the function body itself (without setting unbounded variables to dataset access).
        // TODO(buyingyi): throw an exception for recursive function definition or limit the stack depth.
        implem.setFuncBody(rewriteFunctionBody(implem.getFuncBody()));
        // it's one of the functions we want to inline
        List<LetClause> clauses = new ArrayList<>();
        Iterator<VarIdentifier> paramIter = implem.getParamList().iterator();
        VariableSubstitutionEnvironment subts = new VariableSubstitutionEnvironment();
        for (Expression e : f.getExprList()) {
            VarIdentifier param = paramIter.next();
            // variable inlining to take care of this.
            if (e.getKind() == Kind.VARIABLE_EXPRESSION) {
                subts.addSubstituion(new VariableExpr(param), e);
            } else {
                VarIdentifier newV = context.newVariable();
                Pair<ILangExpression, VariableSubstitutionEnvironment> p1 = e.accept(cloneVisitor, new VariableSubstitutionEnvironment());
                LetClause c = new LetClause(new VariableExpr(newV), (Expression) p1.first);
                clauses.add(c);
                subts.addSubstituion(new VariableExpr(param), new VariableExpr(newV));
            }
        }
        Pair<ILangExpression, VariableSubstitutionEnvironment> p2 = implem.getFuncBody().accept(cloneVisitor, subts);
        Expression resExpr;
        if (clauses.isEmpty()) {
            resExpr = (Expression) p2.first;
        } else {
            resExpr = generateQueryExpression(clauses, (Expression) p2.first);
        }
        return new Pair<>(true, resExpr);
    }
}
Also used : LetClause(org.apache.asterix.lang.common.clause.LetClause) ArrayList(java.util.ArrayList) FunctionDecl(org.apache.asterix.lang.common.statement.FunctionDecl) VariableSubstitutionEnvironment(org.apache.asterix.lang.common.rewrites.VariableSubstitutionEnvironment) VarIdentifier(org.apache.asterix.lang.common.struct.VarIdentifier) ILangExpression(org.apache.asterix.lang.common.base.ILangExpression) QuantifiedExpression(org.apache.asterix.lang.common.expression.QuantifiedExpression) Expression(org.apache.asterix.lang.common.base.Expression) CallExpr(org.apache.asterix.lang.common.expression.CallExpr) VariableExpr(org.apache.asterix.lang.common.expression.VariableExpr) ILangExpression(org.apache.asterix.lang.common.base.ILangExpression) GbyVariableExpressionPair(org.apache.asterix.lang.common.expression.GbyVariableExpressionPair) Pair(org.apache.hyracks.algebricks.common.utils.Pair) QuantifiedPair(org.apache.asterix.lang.common.struct.QuantifiedPair)

Example 3 with FunctionDecl

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

the class CloneAndSubstituteVariablesVisitor method visit.

@Override
public Pair<ILangExpression, VariableSubstitutionEnvironment> visit(FunctionDecl fd, VariableSubstitutionEnvironment env) throws CompilationException {
    List<VarIdentifier> newList = new ArrayList<>(fd.getParamList().size());
    for (VarIdentifier vi : fd.getParamList()) {
        VariableExpr varExpr = new VariableExpr(vi);
        if (!env.constainsOldVar(varExpr)) {
            throw new CompilationException("Parameter " + vi + " does not appear in the substitution list.");
        }
        Expression newExpr = env.findSubstitution(varExpr);
        if (newExpr.getKind() != Kind.VARIABLE_EXPRESSION) {
            throw new CompilationException("Parameter " + vi + " cannot be substituted by a non-variable expression.");
        }
        newList.add(((VariableExpr) newExpr).getVar());
    }
    Pair<ILangExpression, VariableSubstitutionEnvironment> p1 = fd.getFuncBody().accept(this, env);
    FunctionDecl newF = new FunctionDecl(fd.getSignature(), newList, (Expression) p1.first);
    return new Pair<>(newF, env);
}
Also used : CompilationException(org.apache.asterix.common.exceptions.CompilationException) VariableSubstitutionEnvironment(org.apache.asterix.lang.common.rewrites.VariableSubstitutionEnvironment) VarIdentifier(org.apache.asterix.lang.common.struct.VarIdentifier) ILangExpression(org.apache.asterix.lang.common.base.ILangExpression) QuantifiedExpression(org.apache.asterix.lang.common.expression.QuantifiedExpression) Expression(org.apache.asterix.lang.common.base.Expression) ArrayList(java.util.ArrayList) VariableExpr(org.apache.asterix.lang.common.expression.VariableExpr) ILangExpression(org.apache.asterix.lang.common.base.ILangExpression) FunctionDecl(org.apache.asterix.lang.common.statement.FunctionDecl) GbyVariableExpressionPair(org.apache.asterix.lang.common.expression.GbyVariableExpressionPair) Pair(org.apache.hyracks.algebricks.common.utils.Pair) QuantifiedPair(org.apache.asterix.lang.common.struct.QuantifiedPair)

Example 4 with FunctionDecl

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

the class SqlppQueryRewriter method inlineDeclaredUdfs.

protected void inlineDeclaredUdfs() throws CompilationException {
    List<FunctionSignature> funIds = new ArrayList<FunctionSignature>();
    for (FunctionDecl fdecl : declaredFunctions) {
        funIds.add(fdecl.getSignature());
    }
    List<FunctionDecl> usedStoredFunctionDecls = new ArrayList<>();
    for (Expression topLevelExpr : topExpr.getDirectlyEnclosedExpressions()) {
        usedStoredFunctionDecls.addAll(FunctionUtil.retrieveUsedStoredFunctions(metadataProvider, topLevelExpr, funIds, null, expr -> getFunctionCalls(expr), func -> functionRepository.getFunctionDecl(func), signature -> FunctionMapUtil.normalizeBuiltinFunctionSignature(signature, false)));
    }
    declaredFunctions.addAll(usedStoredFunctionDecls);
    if (!declaredFunctions.isEmpty()) {
        SqlppInlineUdfsVisitor visitor = new SqlppInlineUdfsVisitor(context, new SqlppFunctionBodyRewriterFactory(), /* the rewriter for function bodies expressions*/
        declaredFunctions, metadataProvider);
        while (topExpr.accept(visitor, declaredFunctions)) {
        // loop until no more changes
        }
    }
    declaredFunctions.removeAll(usedStoredFunctionDecls);
}
Also used : UnnestClause(org.apache.asterix.lang.sqlpp.clause.UnnestClause) OperatorExpressionVisitor(org.apache.asterix.lang.sqlpp.rewrites.visitor.OperatorExpressionVisitor) JoinClause(org.apache.asterix.lang.sqlpp.clause.JoinClause) FromTerm(org.apache.asterix.lang.sqlpp.clause.FromTerm) VariableCheckAndRewriteVisitor(org.apache.asterix.lang.sqlpp.rewrites.visitor.VariableCheckAndRewriteVisitor) SqlppGlobalAggregationSugarVisitor(org.apache.asterix.lang.sqlpp.rewrites.visitor.SqlppGlobalAggregationSugarVisitor) InlineColumnAliasVisitor(org.apache.asterix.lang.sqlpp.rewrites.visitor.InlineColumnAliasVisitor) SelectElement(org.apache.asterix.lang.sqlpp.clause.SelectElement) SelectRegular(org.apache.asterix.lang.sqlpp.clause.SelectRegular) FunctionParser(org.apache.asterix.lang.sqlpp.parser.FunctionParser) NestClause(org.apache.asterix.lang.sqlpp.clause.NestClause) ArrayList(java.util.ArrayList) CaseExpression(org.apache.asterix.lang.sqlpp.expression.CaseExpression) HavingClause(org.apache.asterix.lang.sqlpp.clause.HavingClause) IReturningStatement(org.apache.asterix.lang.common.base.IReturningStatement) ISqlppVisitor(org.apache.asterix.lang.sqlpp.visitor.base.ISqlppVisitor) FunctionUtil(org.apache.asterix.lang.common.util.FunctionUtil) LetClause(org.apache.asterix.lang.common.clause.LetClause) SubstituteGroupbyExpressionWithVariableVisitor(org.apache.asterix.lang.sqlpp.rewrites.visitor.SubstituteGroupbyExpressionWithVariableVisitor) SqlppListInputFunctionRewriteVisitor(org.apache.asterix.lang.sqlpp.rewrites.visitor.SqlppListInputFunctionRewriteVisitor) SetOperationRight(org.apache.asterix.lang.sqlpp.struct.SetOperationRight) SelectBlock(org.apache.asterix.lang.sqlpp.clause.SelectBlock) FunctionSignature(org.apache.asterix.common.functions.FunctionSignature) SelectSetOperation(org.apache.asterix.lang.sqlpp.clause.SelectSetOperation) FunctionDecl(org.apache.asterix.lang.common.statement.FunctionDecl) CompilationException(org.apache.asterix.common.exceptions.CompilationException) SelectClause(org.apache.asterix.lang.sqlpp.clause.SelectClause) SqlppInlineUdfsVisitor(org.apache.asterix.lang.sqlpp.rewrites.visitor.SqlppInlineUdfsVisitor) SqlppGroupByVisitor(org.apache.asterix.lang.sqlpp.rewrites.visitor.SqlppGroupByVisitor) Expression(org.apache.asterix.lang.common.base.Expression) Set(java.util.Set) LangRewritingContext(org.apache.asterix.lang.common.rewrites.LangRewritingContext) Projection(org.apache.asterix.lang.sqlpp.clause.Projection) AbstractBinaryCorrelateClause(org.apache.asterix.lang.sqlpp.clause.AbstractBinaryCorrelateClause) SqlppParserFactory(org.apache.asterix.lang.sqlpp.parser.SqlppParserFactory) IQueryRewriter(org.apache.asterix.lang.common.base.IQueryRewriter) SqlppBuiltinFunctionRewriteVisitor(org.apache.asterix.lang.sqlpp.rewrites.visitor.SqlppBuiltinFunctionRewriteVisitor) GatherFunctionCallsVisitor(org.apache.asterix.lang.common.visitor.GatherFunctionCallsVisitor) List(java.util.List) MetadataProvider(org.apache.asterix.metadata.declared.MetadataProvider) GenerateColumnNameVisitor(org.apache.asterix.lang.sqlpp.rewrites.visitor.GenerateColumnNameVisitor) FunctionMapUtil(org.apache.asterix.lang.sqlpp.util.FunctionMapUtil) InlineWithExpressionVisitor(org.apache.asterix.lang.sqlpp.rewrites.visitor.InlineWithExpressionVisitor) SelectExpression(org.apache.asterix.lang.sqlpp.expression.SelectExpression) FromClause(org.apache.asterix.lang.sqlpp.clause.FromClause) IndependentSubquery(org.apache.asterix.lang.sqlpp.expression.IndependentSubquery) SetOperationVisitor(org.apache.asterix.lang.sqlpp.rewrites.visitor.SetOperationVisitor) CaseExpression(org.apache.asterix.lang.sqlpp.expression.CaseExpression) Expression(org.apache.asterix.lang.common.base.Expression) SelectExpression(org.apache.asterix.lang.sqlpp.expression.SelectExpression) ArrayList(java.util.ArrayList) SqlppInlineUdfsVisitor(org.apache.asterix.lang.sqlpp.rewrites.visitor.SqlppInlineUdfsVisitor) FunctionSignature(org.apache.asterix.common.functions.FunctionSignature) FunctionDecl(org.apache.asterix.lang.common.statement.FunctionDecl)

Example 5 with FunctionDecl

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

the class FunctionParser method getFunctionDecl.

public FunctionDecl getFunctionDecl(Function function) throws CompilationException {
    String functionBody = function.getFunctionBody();
    List<String> params = function.getParams();
    StringBuilder builder = new StringBuilder();
    builder.append(" use " + function.getDataverseName() + ";");
    builder.append(" declare function " + function.getName().split("@")[0]);
    builder.append("(");
    for (String param : params) {
        VarIdentifier varId = SqlppVariableUtil.toUserDefinedVariableName(param);
        builder.append(varId);
        builder.append(",");
    }
    if (params.size() > 0) {
        builder.delete(builder.length() - 1, builder.length());
    }
    builder.append(")");
    builder.append("{");
    builder.append("\n");
    builder.append(functionBody);
    builder.append("\n");
    builder.append("}");
    IParser parser = parserFactory.createParser(new StringReader(new String(builder)));
    List<Statement> statements = parser.parse();
    FunctionDecl decl = (FunctionDecl) statements.get(1);
    return decl;
}
Also used : VarIdentifier(org.apache.asterix.lang.common.struct.VarIdentifier) Statement(org.apache.asterix.lang.common.base.Statement) StringReader(java.io.StringReader) IParser(org.apache.asterix.lang.common.base.IParser) FunctionDecl(org.apache.asterix.lang.common.statement.FunctionDecl)

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