blob: 79e90a45a42aef5aa19098e03a00c42d920f055a [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.asterix.lang.common.visitor;
import java.io.PrintWriter;
import java.util.Iterator;
import java.util.List;
import org.apache.asterix.common.config.DatasetConfig.DatasetType;
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.Literal;
import org.apache.asterix.lang.common.clause.LetClause;
import org.apache.asterix.lang.common.clause.LimitClause;
import org.apache.asterix.lang.common.clause.OrderbyClause;
import org.apache.asterix.lang.common.clause.OrderbyClause.NullOrderModifier;
import org.apache.asterix.lang.common.clause.OrderbyClause.OrderModifier;
import org.apache.asterix.lang.common.clause.WhereClause;
import org.apache.asterix.lang.common.expression.CallExpr;
import org.apache.asterix.lang.common.expression.FieldAccessor;
import org.apache.asterix.lang.common.expression.FieldBinding;
import org.apache.asterix.lang.common.expression.IfExpr;
import org.apache.asterix.lang.common.expression.IndexAccessor;
import org.apache.asterix.lang.common.expression.ListConstructor;
import org.apache.asterix.lang.common.expression.LiteralExpr;
import org.apache.asterix.lang.common.expression.OperatorExpr;
import org.apache.asterix.lang.common.expression.OrderedListTypeDefinition;
import org.apache.asterix.lang.common.expression.QuantifiedExpression;
import org.apache.asterix.lang.common.expression.RecordConstructor;
import org.apache.asterix.lang.common.expression.RecordTypeDefinition;
import org.apache.asterix.lang.common.expression.RecordTypeDefinition.RecordKind;
import org.apache.asterix.lang.common.expression.TypeExpression;
import org.apache.asterix.lang.common.expression.TypeReferenceExpression;
import org.apache.asterix.lang.common.expression.UnaryExpr;
import org.apache.asterix.lang.common.expression.UnorderedListTypeDefinition;
import org.apache.asterix.lang.common.expression.VariableExpr;
import org.apache.asterix.lang.common.statement.DatasetDecl;
import org.apache.asterix.lang.common.statement.DataverseDecl;
import org.apache.asterix.lang.common.statement.DisconnectFeedStatement;
import org.apache.asterix.lang.common.statement.FunctionDecl;
import org.apache.asterix.lang.common.statement.InternalDetailsDecl;
import org.apache.asterix.lang.common.statement.Query;
import org.apache.asterix.lang.common.statement.SetStatement;
import org.apache.asterix.lang.common.statement.TypeDecl;
import org.apache.asterix.lang.common.statement.WriteStatement;
import org.apache.asterix.lang.common.struct.OperatorType;
import org.apache.asterix.lang.common.struct.QuantifiedPair;
import org.apache.asterix.lang.common.visitor.base.AbstractQueryExpressionVisitor;
import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
public abstract class QueryPrintVisitor extends AbstractQueryExpressionVisitor<Void, Integer> {
protected final PrintWriter out;
protected QueryPrintVisitor(PrintWriter out) {
this.out = out;
}
protected String skip(int step) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < step; i++) {
sb.append(" ");
}
return sb.toString();
}
@Override
public Void visit(Query q, Integer step) throws CompilationException {
if (q.getBody() != null) {
out.println("Query:");
q.getBody().accept(this, step);
} else {
out.println("No query.");
}
return null;
}
@Override
public Void visit(LiteralExpr l, Integer step) {
Literal lc = l.getValue();
if (lc.getLiteralType().equals(Literal.Type.TRUE) || lc.getLiteralType().equals(Literal.Type.FALSE)
|| lc.getLiteralType().equals(Literal.Type.NULL) || lc.getLiteralType().equals(Literal.Type.MISSING)) {
out.println(skip(step) + "LiteralExpr [" + l.getValue().getLiteralType() + "]");
} else {
out.println(skip(step) + "LiteralExpr [" + l.getValue().getLiteralType() + "] ["
+ l.getValue().getStringValue() + "]");
}
return null;
}
@Override
public Void visit(VariableExpr v, Integer step) {
out.println(skip(step) + "Variable [ Name=" + v.getVar().getValue() + " ]");
return null;
}
@Override
public Void visit(ListConstructor lc, Integer step) throws CompilationException {
boolean ordered = false;
if (lc.getType().equals(ListConstructor.Type.ORDERED_LIST_CONSTRUCTOR)) {
ordered = true;
}
out.println(skip(step) + (ordered ? "OrderedListConstructor " : "UnorderedListConstructor ") + "[");
for (Expression e : lc.getExprList()) {
e.accept(this, step + 1);
}
out.println(skip(step) + "]");
return null;
}
@Override
public Void visit(RecordConstructor rc, Integer step) throws CompilationException {
out.println(skip(step) + "RecordConstructor [");
// fbList accept visitor
for (FieldBinding fb : rc.getFbList()) {
out.println(skip(step + 1) + "(");
fb.getLeftExpr().accept(this, step + 2);
out.println(skip(step + 2) + ":");
fb.getRightExpr().accept(this, step + 2);
out.println(skip(step + 1) + ")");
}
out.println(skip(step) + "]");
return null;
}
@Override
public Void visit(CallExpr callExpr, Integer step) throws CompilationException {
return printFunctionCall(callExpr.getFunctionSignature(), callExpr.getFunctionSignature().getArity(),
callExpr.getExprList(), callExpr.getAggregateFilterExpr(), step);
}
protected Void printFunctionCall(FunctionSignature fs, int arity, List<Expression> argList,
Expression aggFilterExpr, Integer step) throws CompilationException {
out.print(skip(step) + "FunctionCall ");
printFunctionSignature(out, fs, arity);
out.println("[");
for (Expression expr : argList) {
expr.accept(this, step + 1);
}
out.print(skip(step) + "]");
if (aggFilterExpr != null) {
out.println(" filter [");
aggFilterExpr.accept(this, step + 1);
out.print(skip(step) + "]");
}
out.println();
return null;
}
protected static void printFunctionSignature(PrintWriter out, FunctionSignature fs, int arity) {
out.print(fs.toString(false));
if (arity != FunctionIdentifier.VARARGS) {
out.print("@");
out.print(arity);
}
}
@Override
public Void visit(OperatorExpr ifbo, Integer step) throws CompilationException {
List<Expression> exprList = ifbo.getExprList();
List<OperatorType> opList = ifbo.getOpList();
if (ifbo.isCurrentop()) {
out.println(skip(step) + "OperatorExpr [");
exprList.get(0).accept(this, step + 1);
for (int i = 1; i < exprList.size(); i++) {
out.println(skip(step + 1) + opList.get(i - 1));
exprList.get(i).accept(this, step + 1);
}
out.println(skip(step) + "]");
} else {
exprList.get(0).accept(this, step);
}
return null;
}
@Override
public Void visit(IfExpr ifexpr, Integer step) throws CompilationException {
out.println(skip(step) + "IfExpr [");
out.println(skip(step + 1) + "Condition:");
ifexpr.getCondExpr().accept(this, step + 2);
out.println(skip(step + 1) + "Then:");
ifexpr.getThenExpr().accept(this, step + 2);
out.println(skip(step + 1) + "Else:");
ifexpr.getElseExpr().accept(this, step + 2);
out.println(skip(step) + "]");
return null;
}
@Override
public Void visit(QuantifiedExpression qe, Integer step) throws CompilationException {
out.println(skip(step) + "QuantifiedExpression " + qe.getQuantifier() + " [");
// quantifiedList accept visitor
for (QuantifiedPair pair : qe.getQuantifiedList()) {
out.print(skip(step + 1) + "[");
pair.getVarExpr().accept(this, 0);
out.println(skip(step + 1) + "In");
pair.getExpr().accept(this, step + 2);
out.println(skip(step + 1) + "]");
}
out.println(skip(step + 1) + "Satifies [");
qe.getSatisfiesExpr().accept(this, step + 2);
out.println(skip(step + 1) + "]");// for satifies
out.println(skip(step) + "]");// for quantifiedExpr
return null;
}
@Override
public Void visit(LetClause lc, Integer step) throws CompilationException {
out.print(skip(step) + "Let ");
lc.getVarExpr().accept(this, 0);
out.println(skip(step + 1) + ":=");
lc.getBindingExpr().accept(this, step + 1);
return null;
}
@Override
public Void visit(WhereClause wc, Integer step) throws CompilationException {
out.println(skip(step) + "Where");
wc.getWhereExpr().accept(this, step + 1);
return null;
}
@Override
public Void visit(OrderbyClause oc, Integer step) throws CompilationException {
out.println(skip(step) + "Orderby");
List<OrderModifier> mlist = oc.getModifierList();
List<NullOrderModifier> nlist = oc.getNullModifierList();
List<Expression> list = oc.getOrderbyList();
for (int i = 0; i < list.size(); i++) {
list.get(i).accept(this, step + 1);
OrderModifier orderModifier = mlist.get(i);
NullOrderModifier nullOrderModifier = nlist.get(i);
out.println(
skip(step + 1) + orderModifier + (nullOrderModifier != null ? " NULLS " + nullOrderModifier : ""));
}
out.println();
return null;
}
@Override
public Void visit(LimitClause lc, Integer step) throws CompilationException {
if (lc.hasLimitExpr()) {
out.println(skip(step) + "Limit");
lc.getLimitExpr().accept(this, step + 1);
if (lc.hasOffset()) {
out.println(skip(step + 1) + "Offset");
lc.getOffset().accept(this, step + 2);
}
} else if (lc.hasOffset()) {
out.println(skip(step) + "Offset");
lc.getOffset().accept(this, step + 1);
} else {
throw new CompilationException(ErrorCode.COMPILATION_ILLEGAL_STATE, lc.getSourceLocation(), "");
}
return null;
}
@Override
public Void visit(FunctionDecl fd, Integer step) throws CompilationException {
out.println(skip(step) + "FunctionDecl " + fd.getSignature().getName() + "(" + fd.getParamList().toString()
+ ") {");
fd.getFuncBody().accept(this, step + 1);
out.println(skip(step) + "}");
out.println();
return null;
}
@Override
public Void visit(UnaryExpr u, Integer step) throws CompilationException {
if (u.getExprType() != null) {
out.print(skip(step) + u.getExprType() + " ");
u.getExpr().accept(this, 0);
} else {
u.getExpr().accept(this, step);
}
return null;
}
@Override
public Void visit(FieldAccessor fa, Integer step) throws CompilationException {
out.println(skip(step) + "FieldAccessor [");
fa.getExpr().accept(this, step + 1);
out.println(skip(step + 1) + "Field=" + fa.getIdent().getValue());
out.println(skip(step) + "]");
return null;
}
@Override
public Void visit(IndexAccessor ia, Integer step) throws CompilationException {
out.println(skip(step) + "IndexAccessor [");
ia.getExpr().accept(this, step + 1);
out.print(skip(step + 1) + "Index: ");
switch (ia.getIndexKind()) {
case ANY:
out.println("ANY");
break;
case STAR:
out.println("STAR");
break;
case ELEMENT:
ia.getIndexExpr().accept(this, step + 1);
break;
default:
throw new CompilationException(ErrorCode.COMPILATION_ILLEGAL_STATE, ia.getSourceLocation(),
ia.getIndexKind());
}
out.println(skip(step) + "]");
return null;
}
@Override
public Void visit(TypeDecl t, Integer step) throws CompilationException {
out.println(skip(step) + "TypeDecl " + t.getIdent() + " [");
t.getTypeDef().accept(this, step + 1);
out.println(skip(step) + "]");
return null;
}
@Override
public Void visit(TypeReferenceExpression t, Integer arg) throws CompilationException {
if (t.getIdent().first != null && t.getIdent().first != null) {
out.print(t.getIdent().first);
out.print('.');
}
out.print(t.getIdent().second.getValue());
return null;
}
@Override
public Void visit(RecordTypeDefinition r, Integer step) throws CompilationException {
if (r.getRecordKind() == RecordKind.CLOSED) {
out.print(skip(step) + "closed ");
} else {
out.print(skip(step) + "open ");
}
out.println("RecordType {");
Iterator<String> nameIter = r.getFieldNames().iterator();
Iterator<TypeExpression> typeIter = r.getFieldTypes().iterator();
Iterator<Boolean> isNullableIter = r.getNullableFields().iterator();
Iterator<Boolean> isMissableIter = r.getMissableFields().iterator();
boolean first = true;
while (nameIter.hasNext()) {
if (first) {
first = false;
} else {
out.println(",");
}
String name = nameIter.next();
TypeExpression texp = typeIter.next();
Boolean isNullable = isNullableIter.next();
Boolean isMissable = isMissableIter.next();
out.print(skip(step + 1) + name + " : ");
texp.accept(this, step + 2);
if (isNullable || isMissable) {
out.print("?");
}
}
out.println();
out.println(skip(step) + "}");
return null;
}
@Override
public Void visit(OrderedListTypeDefinition x, Integer step) throws CompilationException {
out.print("OrderedList [");
x.getItemTypeExpression().accept(this, step + 2);
out.println("]");
return null;
}
@Override
public Void visit(UnorderedListTypeDefinition x, Integer step) throws CompilationException {
out.print("UnorderedList <");
x.getItemTypeExpression().accept(this, step + 2);
out.println(">");
return null;
}
@Override
public Void visit(DatasetDecl dd, Integer step) throws CompilationException {
if (dd.getDatasetType() == DatasetType.INTERNAL) {
out.print(skip(step) + "DatasetDecl " + dd.getName() + "(");
dd.getItemType().accept(this, step + 2);
out.print(skip(step) + ") partitioned by "
+ ((InternalDetailsDecl) dd.getDatasetDetailsDecl()).getPartitioningExprs());
if (((InternalDetailsDecl) dd.getDatasetDetailsDecl()).isAutogenerated()) {
out.print(" [autogenerated]");
}
out.println();
} else if (dd.getDatasetType() == DatasetType.EXTERNAL) {
out.print(skip(step) + "DatasetDecl " + dd.getName() + "(");
dd.getItemType().accept(this, step + 2);
out.println(skip(step) + ")is an external dataset");
}
return null;
}
@Override
public Void visit(DataverseDecl dv, Integer step) throws CompilationException {
out.println(skip(step) + "DataverseUse " + dv.getDataverseName());
return null;
}
@Override
public Void visit(WriteStatement ws, Integer step) throws CompilationException {
out.print(skip(step) + "WriteOutputTo " + ws.getNcName() + ":" + ws.getFileName());
if (ws.getWriterClassName() != null) {
out.print(" using " + ws.getWriterClassName());
}
out.println();
return null;
}
@Override
public Void visit(SetStatement ss, Integer step) throws CompilationException {
out.println(skip(step) + "Set " + ss.getPropName() + "=" + ss.getPropValue());
return null;
}
@Override
public Void visit(DisconnectFeedStatement ss, Integer step) throws CompilationException {
out.println(skip(step) + skip(step) + ss.getFeedName() + skip(step) + ss.getDatasetName());
return null;
}
}