/* * JBoss, Home of Professional Open Source. * See the COPYRIGHT.txt file distributed with this work for information * regarding copyright ownership. Some portions may be licensed * to Red Hat, Inc. under one or more contributor license agreements. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301 USA. */ package org.teiid.query.sql.navigator; import java.util.Collection; import org.teiid.query.sql.LanguageObject; import org.teiid.query.sql.LanguageVisitor; import org.teiid.query.sql.lang.*; import org.teiid.query.sql.proc.*; import org.teiid.query.sql.symbol.*; /** * @since 4.2 */ public class PreOrPostOrderNavigator extends AbstractNavigator { public static final boolean PRE_ORDER = true; public static final boolean POST_ORDER = false; private boolean order; private boolean deep; private boolean skipEvaluatable; public PreOrPostOrderNavigator(LanguageVisitor visitor, boolean order, boolean deep) { super(visitor); this.order = order; this.deep = deep; } protected void preVisitVisitor(LanguageObject obj) { if(order == PRE_ORDER) { visitVisitor(obj); } } protected void postVisitVisitor(LanguageObject obj) { if(order == POST_ORDER) { visitVisitor(obj); } } public void visit(AggregateSymbol obj) { preVisitVisitor(obj); Expression[] args = obj.getArgs(); if(args != null) { for(int i=0; i<args.length; i++) { visitNode(args[i]); } } visitNode(obj.getOrderBy()); visitNode(obj.getCondition()); postVisitVisitor(obj); } public void visit(AliasSymbol obj) { preVisitVisitor(obj); visitNode(obj.getSymbol()); postVisitVisitor(obj); } public void visit(MultipleElementSymbol obj) { preVisitVisitor(obj); postVisitVisitor(obj); } public void visit(AssignmentStatement obj) { preVisitVisitor(obj); visitNode(obj.getVariable()); visitNode(obj.getExpression()); postVisitVisitor(obj); } public void visit(BatchedUpdateCommand obj) { preVisitVisitor(obj); visitNodes(obj.getUpdateCommands()); postVisitVisitor(obj); } public void visit(BetweenCriteria obj) { preVisitVisitor(obj); visitNode(obj.getExpression()); visitNode(obj.getLowerExpression()); visitNode(obj.getUpperExpression()); postVisitVisitor(obj); } public void visit(Block obj) { preVisitVisitor(obj); visitNodes(obj.getStatements()); visitNodes(obj.getExceptionStatements()); postVisitVisitor(obj); } public void visit(BranchingStatement obj) { preVisitVisitor(obj); postVisitVisitor(obj); } public void visit(CaseExpression obj) { preVisitVisitor(obj); visitNode(obj.getExpression()); for(int i=0; i<obj.getWhenCount(); i++) { visitNode(obj.getWhenExpression(i)); visitNode(obj.getThenExpression(i)); } visitNode(obj.getElseExpression()); postVisitVisitor(obj); } public void visit(CommandStatement obj) { preVisitVisitor(obj); if (deep) { visitNode(obj.getCommand()); } postVisitVisitor(obj); } public void visit(CompareCriteria obj) { preVisitVisitor(obj); visitNode(obj.getLeftExpression()); visitNode(obj.getRightExpression()); postVisitVisitor(obj); } public void visit(CompoundCriteria obj) { preVisitVisitor(obj); visitNodes(obj.getCriteria()); postVisitVisitor(obj); } public void visit(Constant obj) { preVisitVisitor(obj); postVisitVisitor(obj); } public void visit(CreateProcedureCommand obj) { preVisitVisitor(obj); visitNode(obj.getBlock()); postVisitVisitor(obj); } public void visit(DeclareStatement obj) { preVisitVisitor(obj); visitNode(obj.getVariable()); visitNode(obj.getExpression()); postVisitVisitor(obj); } public void visit(Delete obj) { preVisitVisitor(obj); visitNode(obj.getGroup()); visitNode(obj.getCriteria()); visitNode(obj.getOption()); postVisitVisitor(obj); } public void visit(DependentSetCriteria obj) { preVisitVisitor(obj); visitNode(obj.getExpression()); postVisitVisitor(obj); } public void visit(ElementSymbol obj) { preVisitVisitor(obj); postVisitVisitor(obj); } public void visit(ExistsCriteria obj) { preVisitVisitor(obj); if (deep && (!obj.shouldEvaluate() || !skipEvaluatable)) { visitNode(obj.getCommand()); } postVisitVisitor(obj); } public void visit(ExpressionSymbol obj) { preVisitVisitor(obj); visitNode(obj.getExpression()); postVisitVisitor(obj); } public void visit(From obj) { preVisitVisitor(obj); visitNodes(obj.getClauses()); postVisitVisitor(obj); } public void visit(Function obj) { preVisitVisitor(obj); Expression[] args = obj.getArgs(); if(args != null) { for(int i=0; i<args.length; i++) { visitNode(args[i]); } } postVisitVisitor(obj); } public void visit(GroupBy obj) { preVisitVisitor(obj); visitNodes(obj.getSymbols()); postVisitVisitor(obj); } public void visit(GroupSymbol obj) { preVisitVisitor(obj); postVisitVisitor(obj); } public void visit(IfStatement obj) { preVisitVisitor(obj); visitNode(obj.getCondition()); visitNode(obj.getIfBlock()); visitNode(obj.getElseBlock()); postVisitVisitor(obj); } public void visit(Insert obj) { preVisitVisitor(obj); visitNode(obj.getGroup()); visitNodes(obj.getVariables()); visitNodes(obj.getValues()); if(deep && obj.getQueryExpression()!=null) { visitNode(obj.getQueryExpression()); } visitNode(obj.getOption()); postVisitVisitor(obj); } public void visit(Create obj) { preVisitVisitor(obj); visitNode(obj.getTable()); visitNodes(obj.getColumnSymbols()); visitNodes(obj.getPrimaryKey()); postVisitVisitor(obj); } public void visit(Drop obj) { preVisitVisitor(obj); visitNode(obj.getTable()); postVisitVisitor(obj); } public void visit(Into obj) { preVisitVisitor(obj); visitNode(obj.getGroup()); postVisitVisitor(obj); } public void visit(IsNullCriteria obj) { preVisitVisitor(obj); visitNode(obj.getExpression()); postVisitVisitor(obj); } public void visit(JoinPredicate obj) { preVisitVisitor(obj); visitNode(obj.getLeftClause()); visitNode(obj.getJoinType()); visitNode(obj.getRightClause()); visitNodes(obj.getJoinCriteria()); postVisitVisitor(obj); } public void visit(JoinType obj) { preVisitVisitor(obj); postVisitVisitor(obj); } public void visit(Limit obj) { preVisitVisitor(obj); visitNode(obj.getOffset()); visitNode(obj.getRowLimit()); postVisitVisitor(obj); } public void visit(LoopStatement obj) { preVisitVisitor(obj); if (deep) { visitNode(obj.getCommand()); } visitNode(obj.getBlock()); postVisitVisitor(obj); } public void visit(MatchCriteria obj) { preVisitVisitor(obj); visitNode(obj.getLeftExpression()); visitNode(obj.getRightExpression()); postVisitVisitor(obj); } public void visit(NotCriteria obj) { preVisitVisitor(obj); visitNode(obj.getCriteria()); postVisitVisitor(obj); } public void visit(Option obj) { preVisitVisitor(obj); postVisitVisitor(obj); } public void visit(OrderBy obj) { preVisitVisitor(obj); visitNodes(obj.getOrderByItems()); postVisitVisitor(obj); } @Override public void visit(OrderByItem obj) { preVisitVisitor(obj); visitNode(obj.getSymbol()); postVisitVisitor(obj); } public void visit(Query obj) { preVisitVisitor(obj); visitNodes(obj.getWith()); visitNode(obj.getSelect()); visitNode(obj.getInto()); visitNode(obj.getFrom()); visitNode(obj.getCriteria()); visitNode(obj.getGroupBy()); visitNode(obj.getHaving()); visitNode(obj.getOrderBy()); visitNode(obj.getLimit()); visitNode(obj.getOption()); postVisitVisitor(obj); } public void visit(RaiseStatement obj) { preVisitVisitor(obj); visitNode(obj.getExpression()); postVisitVisitor(obj); } public void visit(Reference obj) { preVisitVisitor(obj); postVisitVisitor(obj); } public void visit(ScalarSubquery obj) { preVisitVisitor(obj); if (deep && (!obj.shouldEvaluate() || !skipEvaluatable)) { visitNode(obj.getCommand()); } postVisitVisitor(obj); } public void visit(SearchedCaseExpression obj) { preVisitVisitor(obj); for(int i=0; i<obj.getWhenCount(); i++) { visitNode(obj.getWhenCriteria(i)); visitNode(obj.getThenExpression(i)); } visitNode(obj.getElseExpression()); postVisitVisitor(obj); } public void visit(Select obj) { preVisitVisitor(obj); visitNodes(obj.getSymbols()); postVisitVisitor(obj); } public void visit(SetCriteria obj) { preVisitVisitor(obj); visitNode(obj.getExpression()); visitNodes(obj.getValues()); postVisitVisitor(obj); } public void visit(SetQuery obj) { preVisitVisitor(obj); visitNodes(obj.getWith()); visitNodes(obj.getQueryCommands()); visitNode(obj.getOrderBy()); visitNode(obj.getLimit()); visitNode(obj.getOption()); postVisitVisitor(obj); } public void visit(StoredProcedure obj) { preVisitVisitor(obj); Collection<SPParameter> params = obj.getParameters(); if(params != null && !params.isEmpty()) { for (SPParameter parameter : params) { Expression expression = parameter.getExpression(); visitNode(expression); } } visitNode(obj.getOption()); postVisitVisitor(obj); } public void visit(SubqueryCompareCriteria obj) { preVisitVisitor(obj); visitNode(obj.getLeftExpression()); if (deep) { visitNode(obj.getCommand()); } visitNode(obj.getArrayExpression()); postVisitVisitor(obj); } public void visit(SubqueryFromClause obj) { preVisitVisitor(obj); if (deep) { visitNode(obj.getCommand()); } visitNode(obj.getGroupSymbol()); postVisitVisitor(obj); } public void visit(SubquerySetCriteria obj) { preVisitVisitor(obj); visitNode(obj.getExpression()); if (deep) { visitNode(obj.getCommand()); } postVisitVisitor(obj); } public void visit(UnaryFromClause obj) { preVisitVisitor(obj); visitNode(obj.getGroup()); postVisitVisitor(obj); } public void visit(Update obj) { preVisitVisitor(obj); visitNode(obj.getGroup()); visitNode(obj.getChangeList()); visitNode(obj.getCriteria()); visitNode(obj.getOption()); postVisitVisitor(obj); } public void visit(WhileStatement obj) { preVisitVisitor(obj); visitNode(obj.getCondition()); visitNode(obj.getBlock()); postVisitVisitor(obj); } /** * NOTE: we specifically don't need to visit the as columns or the using identifiers. * These will be resolved by the dynamic command resolver instead. * * @see org.teiid.query.sql.LanguageVisitor#visit(org.teiid.query.sql.lang.DynamicCommand) */ public void visit(DynamicCommand obj) { preVisitVisitor(obj); visitNode(obj.getSql()); visitNode(obj.getIntoGroup()); if (obj.getUsing() != null) { for (SetClause setClause : obj.getUsing().getClauses()) { visitNode(setClause.getValue()); } } postVisitVisitor(obj); } public void visit(SetClauseList obj) { preVisitVisitor(obj); visitNodes(obj.getClauses()); postVisitVisitor(obj); } public void visit(SetClause obj) { preVisitVisitor(obj); visitNode(obj.getSymbol()); visitNode(obj.getValue()); postVisitVisitor(obj); } @Override public void visit(TextLine obj) { preVisitVisitor(obj); visitNodes(obj.getExpressions()); postVisitVisitor(obj); } @Override public void visit(XMLForest obj) { preVisitVisitor(obj); visitNode(obj.getNamespaces()); visitNodes(obj.getArgs()); postVisitVisitor(obj); } @Override public void visit(JSONObject obj) { preVisitVisitor(obj); visitNodes(obj.getArgs()); postVisitVisitor(obj); } @Override public void visit(XMLAttributes obj) { preVisitVisitor(obj); visitNodes(obj.getArgs()); postVisitVisitor(obj); } @Override public void visit(XMLElement obj) { preVisitVisitor(obj); visitNode(obj.getNamespaces()); visitNode(obj.getAttributes()); visitNodes(obj.getContent()); postVisitVisitor(obj); } @Override public void visit(XMLNamespaces obj) { preVisitVisitor(obj); postVisitVisitor(obj); } @Override public void visit(TextTable obj) { preVisitVisitor(obj); visitNode(obj.getFile()); visitNode(obj.getGroupSymbol()); postVisitVisitor(obj); } @Override public void visit(XMLTable obj) { preVisitVisitor(obj); visitNode(obj.getNamespaces()); visitNodes(obj.getPassing()); for (XMLTable.XMLColumn column : obj.getColumns()) { visitNode(column.getDefaultExpression()); } visitNode(obj.getGroupSymbol()); postVisitVisitor(obj); } @Override public void visit(ObjectTable obj) { preVisitVisitor(obj); visitNodes(obj.getPassing()); for (ObjectTable.ObjectColumn column : obj.getColumns()) { visitNode(column.getDefaultExpression()); } visitNode(obj.getGroupSymbol()); postVisitVisitor(obj); } @Override public void visit(XMLQuery obj) { preVisitVisitor(obj); visitNode(obj.getNamespaces()); visitNodes(obj.getPassing()); postVisitVisitor(obj); } @Override public void visit(XMLExists obj) { preVisitVisitor(obj); visitNode(obj.getXmlQuery().getNamespaces()); visitNodes(obj.getXmlQuery().getPassing()); postVisitVisitor(obj); } @Override public void visit(XMLCast obj) { preVisitVisitor(obj); visitNode(obj.getExpression()); postVisitVisitor(obj); } @Override public void visit(DerivedColumn obj) { preVisitVisitor(obj); visitNode(obj.getExpression()); postVisitVisitor(obj); } @Override public void visit(XMLSerialize obj) { preVisitVisitor(obj); visitNode(obj.getExpression()); postVisitVisitor(obj); } @Override public void visit(QueryString obj) { preVisitVisitor(obj); visitNode(obj.getPath()); visitNodes(obj.getArgs()); postVisitVisitor(obj); } @Override public void visit(XMLParse obj) { preVisitVisitor(obj); visitNode(obj.getExpression()); postVisitVisitor(obj); } @Override public void visit(ExpressionCriteria obj) { preVisitVisitor(obj); visitNode(obj.getExpression()); postVisitVisitor(obj); } @Override public void visit(WithQueryCommand obj) { preVisitVisitor(obj); visitNodes(obj.getColumns()); if (deep) { visitNode(obj.getCommand()); } postVisitVisitor(obj); } @Override public void visit(TriggerAction obj) { preVisitVisitor(obj); visitNode(obj.getBlock()); postVisitVisitor(obj); } @Override public void visit(ArrayTable obj) { preVisitVisitor(obj); visitNode(obj.getArrayValue()); visitNode(obj.getGroupSymbol()); postVisitVisitor(obj); } @Override public void visit(AlterProcedure obj) { preVisitVisitor(obj); visitNode(obj.getTarget()); if (deep) { visitNode(obj.getDefinition()); } postVisitVisitor(obj); } @Override public void visit(AlterTrigger obj) { preVisitVisitor(obj); visitNode(obj.getTarget()); if (deep) { visitNode(obj.getDefinition()); } postVisitVisitor(obj); } @Override public void visit(AlterView obj) { preVisitVisitor(obj); visitNode(obj.getTarget()); if (deep) { visitNode(obj.getDefinition()); } postVisitVisitor(obj); } @Override public void visit(WindowFunction obj) { preVisitVisitor(obj); visitNode(obj.getFunction()); visitNode(obj.getWindowSpecification()); postVisitVisitor(obj); } @Override public void visit(WindowSpecification obj) { preVisitVisitor(obj); visitNodes(obj.getPartition()); visitNode(obj.getOrderBy()); postVisitVisitor(obj); } @Override public void visit(Array array) { preVisitVisitor(array); visitNodes(array.getExpressions()); postVisitVisitor(array); } @Override public void visit(ExceptionExpression exceptionExpression) { preVisitVisitor(exceptionExpression); visitNode(exceptionExpression.getMessage()); visitNode(exceptionExpression.getSqlState()); visitNode(exceptionExpression.getErrorCode()); visitNode(exceptionExpression.getParent()); postVisitVisitor(exceptionExpression); } @Override public void visit(ReturnStatement obj) { preVisitVisitor(obj); visitNode(obj.getExpression()); postVisitVisitor(obj); } @Override public void visit(IsDistinctCriteria obj) { preVisitVisitor(obj); //don't visit as that will fail the validation that scalar/row value groupsymbols can't be referenced //visitNode(obj.getLeftRowValue()); //visitNode(obj.getRightRowValue()); postVisitVisitor(obj); } public static void doVisit(LanguageObject object, LanguageVisitor visitor, boolean order) { doVisit(object, visitor, order, false); } public static void doVisit(LanguageObject object, LanguageVisitor visitor, boolean order, boolean deep) { PreOrPostOrderNavigator nav = new PreOrPostOrderNavigator(visitor, order, deep); object.acceptVisitor(nav); } public void setSkipEvaluatable(boolean skipEvaluatable) { this.skipEvaluatable = skipEvaluatable; } }