| /* |
| * 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; |
| } |
| |
| } |