use of org.apache.asterix.lang.aql.expression.FLWOGRExpression in project asterixdb by apache.
the class ClauseComparator method visit.
@Override
public Void visit(FLWOGRExpression flwor, Integer step) throws CompilationException {
if (step != 0) {
out.println("(");
}
List<Clause> clauseList = new ArrayList<Clause>();
clauseList.addAll(flwor.getClauseList());
// Processes data-independent let clauses.
if (hasFor(clauseList)) {
processLeadingLetClauses(step, clauseList);
}
// Distill unnecessary order-bys before a group-by.
distillRedundantOrderby(clauseList);
// Correlated "for" clauses after group-by.
Pair<GroupbyClause, List<Clause>> extraction = extractUnnestAfterGroupby(clauseList);
GroupbyClause cuttingGbyClause = extraction.first;
List<Clause> unnestClauseList = extraction.second;
Expression returnExpr = flwor.getReturnExpr();
if (unnestClauseList.size() == 0) {
if (hasFor(clauseList)) {
out.print(skip(step) + "select element ");
returnExpr.accept(this, step + 2);
out.println();
} else {
// The FLOWGR only contains let-return, then inline let binding expressions into the return expression.
Map<VariableExpr, Expression> varExprMap = extractLetBindingVariables(clauseList, cuttingGbyClause);
returnExpr = (Expression) AQLVariableSubstitutionUtil.substituteVariable(returnExpr, varExprMap);
returnExpr.accept(this, step);
return null;
}
}
String generated = generateVariableSymbol();
if (unnestClauseList.size() > 0) {
Map<VariableExpr, Expression> varExprMap = extractDefinedCollectionVariables(clauseList, cuttingGbyClause, generated);
returnExpr = (Expression) AQLVariableSubstitutionUtil.substituteVariable(returnExpr, varExprMap);
List<Clause> newUnnestClauses = new ArrayList<Clause>();
for (Clause nestedCl : unnestClauseList) {
newUnnestClauses.add((Clause) AQLVariableSubstitutionUtil.substituteVariable(nestedCl, varExprMap));
}
unnestClauseList = newUnnestClauses;
out.print(skip(step) + "select element " + (hasDistinct(unnestClauseList) ? "distinct " : ""));
returnExpr.accept(this, step + 2);
out.println();
out.println(skip(step) + "from");
out.print(skip(step + 2) + "( select element " + (hasDistinct(clauseList) ? "distinct " : "") + "{");
int index = 0;
int size = varExprMap.size();
for (VariableExpr var : varExprMap.keySet()) {
out.print("\'" + var.getVar().getValue().substring(1) + "\':" + var.getVar().getValue().substring(1));
if (++index < size) {
out.print(COMMA);
}
}
out.println("}");
}
reorder(clauseList);
reorder(unnestClauseList);
mergeConsecutiveWhereClauses(clauseList);
mergeConsecutiveWhereClauses(unnestClauseList);
boolean firstFor = true;
boolean firstLet = true;
int forStep = unnestClauseList.size() == 0 ? step : step + 3;
int size = clauseList.size();
// "for"s.
for (int i = 0; i < size; ++i) {
Clause cl = clauseList.get(i);
if (cl.getClauseType() == ClauseType.FOR_CLAUSE) {
boolean hasConsequentFor = false;
if (i < size - 1) {
Clause nextCl = clauseList.get(i + 1);
hasConsequentFor = nextCl.getClauseType() == ClauseType.FOR_CLAUSE;
}
visitForClause((ForClause) cl, forStep, firstFor, hasConsequentFor);
firstFor = false;
} else if (cl.getClauseType() == ClauseType.LET_CLAUSE) {
boolean hasConsequentLet = false;
if (i < size - 1) {
Clause nextCl = clauseList.get(i + 1);
hasConsequentLet = nextCl.getClauseType() == ClauseType.LET_CLAUSE;
}
visitLetClause((LetClause) cl, forStep, firstLet, hasConsequentLet);
firstLet = false;
} else {
cl.accept(this, forStep);
}
if (cl.getClauseType() == ClauseType.FROM_CLAUSE || cl.getClauseType() == ClauseType.GROUP_BY_CLAUSE) {
firstLet = true;
}
}
if (unnestClauseList.size() > 0) {
out.println(skip(forStep - 1) + ") as " + generated.substring(1) + ",");
for (Clause nestedCl : unnestClauseList) {
if (nestedCl.getClauseType() == ClauseType.FOR_CLAUSE) {
visitForClause((ForClause) nestedCl, step - 1, firstFor, false);
} else {
nestedCl.accept(this, step);
}
}
}
if (step > 0) {
out.print(skip(step - 2) + ")");
}
return null;
}
use of org.apache.asterix.lang.aql.expression.FLWOGRExpression in project asterixdb by apache.
the class AQLInlineUdfsVisitor method visit.
@Override
public Boolean visit(FLWOGRExpression flwor, List<FunctionDecl> arg) throws CompilationException {
boolean changed = false;
for (Clause c : flwor.getClauseList()) {
if (c.accept(this, arg)) {
changed = true;
}
}
Pair<Boolean, Expression> p = inlineUdfsInExpr(flwor.getReturnExpr(), arg);
flwor.setReturnExpr(p.second);
return changed || p.first;
}
use of org.apache.asterix.lang.aql.expression.FLWOGRExpression in project asterixdb by apache.
the class AqlExpressionToPlanTranslator method expressionNeedsNoNesting.
@Override
protected boolean expressionNeedsNoNesting(Expression expr) {
boolean isFLWOGR = expr.getKind() == Kind.FLWOGR_EXPRESSION;
boolean letOnly = true;
// No nesting is needed for a FLWOR expression that only has LETs and RETURN.
if (isFLWOGR) {
FLWOGRExpression flwor = (FLWOGRExpression) expr;
for (Clause clause : flwor.getClauseList()) {
letOnly &= clause.getClauseType() == Clause.ClauseType.LET_CLAUSE;
}
}
return (isFLWOGR && letOnly) || super.expressionNeedsNoNesting(expr);
}
use of org.apache.asterix.lang.aql.expression.FLWOGRExpression in project asterixdb by apache.
the class AqlExpressionToPlanTranslator method visit.
@Override
public Pair<ILogicalOperator, LogicalVariable> visit(FLWOGRExpression flwor, Mutable<ILogicalOperator> tupSource) throws CompilationException {
Mutable<ILogicalOperator> flworPlan = tupSource;
boolean isTop = context.isTopFlwor();
if (!isTop) {
context.enterSubplan();
}
if (isTop) {
context.setTopFlwor(false);
}
for (Clause c : flwor.getClauseList()) {
Pair<ILogicalOperator, LogicalVariable> pC = c.accept(this, flworPlan);
flworPlan = new MutableObject<>(pC.first);
}
Expression r = flwor.getReturnExpr();
boolean noForClause = flwor.noForClause();
Pair<ILogicalOperator, LogicalVariable> result;
if (r.getKind() == Kind.VARIABLE_EXPRESSION) {
VariableExpr v = (VariableExpr) r;
LogicalVariable var = context.getVar(v.getVar().getId());
result = produceFlworPlan(noForClause, isTop, flworPlan, var);
} else {
Mutable<ILogicalOperator> baseOp = new MutableObject<>(flworPlan.getValue());
Pair<ILogicalOperator, LogicalVariable> rRes = r.accept(this, baseOp);
ILogicalOperator rOp = rRes.first;
ILogicalOperator resOp;
if (expressionNeedsNoNesting(r)) {
baseOp.setValue(flworPlan.getValue());
resOp = rOp;
} else {
SubplanOperator s = new SubplanOperator(rOp);
s.getInputs().add(flworPlan);
resOp = s;
baseOp.setValue(new NestedTupleSourceOperator(new MutableObject<ILogicalOperator>(s)));
}
Mutable<ILogicalOperator> resOpRef = new MutableObject<>(resOp);
result = produceFlworPlan(noForClause, isTop, resOpRef, rRes.second);
}
if (!isTop) {
context.exitSubplan();
}
return result;
}
use of org.apache.asterix.lang.aql.expression.FLWOGRExpression in project asterixdb by apache.
the class AqlDeleteRewriteVisitor method visit.
@Override
public Void visit(DeleteStatement deleteStmt, Void visitArg) {
List<Expression> arguments = new ArrayList<>();
Identifier dataverseName = deleteStmt.getDataverseName();
Identifier datasetName = deleteStmt.getDatasetName();
String arg = dataverseName == null ? datasetName.getValue() : dataverseName.getValue() + "." + datasetName.getValue();
LiteralExpr argumentLiteral = new LiteralExpr(new StringLiteral(arg));
arguments.add(argumentLiteral);
CallExpr callExpression = new CallExpr(new FunctionSignature(FunctionConstants.ASTERIX_NS, "dataset", 1), arguments);
List<Clause> clauseList = new ArrayList<>();
VariableExpr var = deleteStmt.getVariableExpr();
Clause forClause = new ForClause(var, callExpression);
clauseList.add(forClause);
Clause whereClause = null;
Expression condition = deleteStmt.getCondition();
if (condition != null) {
whereClause = new WhereClause(condition);
clauseList.add(whereClause);
}
VariableExpr returnExpr = new VariableExpr(var.getVar());
returnExpr.setIsNewVar(false);
FLWOGRExpression flowgr = new FLWOGRExpression(clauseList, returnExpr);
Query query = new Query(false);
query.setBody(flowgr);
deleteStmt.setQuery(query);
return null;
}
Aggregations