blob: a4e90b432b4518652859f0142da4febdbb334409 [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.tajo.engine.planner;
import org.apache.tajo.engine.planner.logical.*;
import java.util.Stack;
public class BasicLogicalPlanVisitor<CONTEXT, RESULT> implements LogicalPlanVisitor<CONTEXT, RESULT> {
/**
* The prehook is called before each node is visited.
*/
@SuppressWarnings("unused")
public void preHook(LogicalPlan plan, LogicalNode node, Stack<LogicalNode> stack, CONTEXT data)
throws PlanningException {
}
/**
* The posthook is called after each node is visited.
*/
@SuppressWarnings("unused")
public void postHook(LogicalPlan plan, LogicalNode node, Stack<LogicalNode> stack, CONTEXT data)
throws PlanningException {
}
public CONTEXT visit(CONTEXT context, LogicalPlan plan, LogicalPlan.QueryBlock block)
throws PlanningException {
visit(context, plan, block, block.getRoot(), new Stack<LogicalNode>());
return context;
}
/**
* visit visits each logicalNode recursively.
*/
public RESULT visit(CONTEXT context, LogicalPlan plan, LogicalPlan.QueryBlock block, LogicalNode node,
Stack<LogicalNode> stack)
throws PlanningException {
RESULT current;
switch (node.getType()) {
case ROOT:
current = visitRoot(context, plan, block, (LogicalRootNode) node, stack);
break;
case EXPRS:
return null;
case PROJECTION:
current = visitProjection(context, plan, block, (ProjectionNode) node, stack);
break;
case LIMIT:
current = visitLimit(context, plan, block, (LimitNode) node, stack);
break;
case SORT:
current = visitSort(context, plan, block, (SortNode) node, stack);
break;
case HAVING:
current = visitHaving(context, plan, block, (HavingNode) node, stack);
break;
case GROUP_BY:
current = visitGroupBy(context, plan, block, (GroupbyNode) node, stack);
break;
case WINDOW_AGG:
current = visitWindowAgg(context, plan, block, (WindowAggNode) node, stack);
break;
case DISTINCT_GROUP_BY:
current = visitDistinct(context, plan, block, (DistinctGroupbyNode) node, stack);
break;
case SELECTION:
current = visitFilter(context, plan, block, (SelectionNode) node, stack);
break;
case JOIN:
current = visitJoin(context, plan, block, (JoinNode) node, stack);
break;
case UNION:
current = visitUnion(context, plan, block, (UnionNode) node, stack);
break;
case EXCEPT:
current = visitExcept(context, plan, block, (ExceptNode) node, stack);
break;
case INTERSECT:
current = visitIntersect(context, plan, block, (IntersectNode) node, stack);
break;
case TABLE_SUBQUERY:
current = visitTableSubQuery(context, plan, block, (TableSubQueryNode) node, stack);
break;
case SCAN:
current = visitScan(context, plan, block, (ScanNode) node, stack);
break;
case PARTITIONS_SCAN:
current = visitPartitionedTableScan(context, plan, block, (PartitionedTableScanNode) node, stack);
break;
case STORE:
current = visitStoreTable(context, plan, block, (StoreTableNode) node, stack);
break;
case INSERT:
current = visitInsert(context, plan, block, (InsertNode) node, stack);
break;
case CREATE_DATABASE:
current = visitCreateDatabase(context, plan, block, (CreateDatabaseNode) node, stack);
break;
case DROP_DATABASE:
current = visitDropDatabase(context, plan, block, (DropDatabaseNode) node, stack);
break;
case CREATE_TABLE:
current = visitCreateTable(context, plan, block, (CreateTableNode) node, stack);
break;
case DROP_TABLE:
current = visitDropTable(context, plan, block, (DropTableNode) node, stack);
break;
case ALTER_TABLESPACE:
current = visitAlterTablespace(context, plan, block, (AlterTablespaceNode) node, stack);
break;
case ALTER_TABLE:
current = visitAlterTable(context, plan, block, (AlterTableNode) node, stack);
break;
case TRUNCATE_TABLE:
current = visitTruncateTable(context, plan, block, (TruncateTableNode) node, stack);
break;
default:
throw new PlanningException("Unknown logical node type: " + node.getType());
}
return current;
}
@Override
public RESULT visitRoot(CONTEXT context, LogicalPlan plan, LogicalPlan.QueryBlock block, LogicalRootNode node,
Stack<LogicalNode> stack) throws PlanningException {
stack.push(node);
RESULT result = visit(context, plan, block, node.getChild(), stack);
stack.pop();
return result;
}
@Override
public RESULT visitProjection(CONTEXT context, LogicalPlan plan, LogicalPlan.QueryBlock block, ProjectionNode node,
Stack<LogicalNode> stack)
throws PlanningException {
stack.push(node);
RESULT result = visit(context, plan, block, node.getChild(), stack);
stack.pop();
return result;
}
@Override
public RESULT visitLimit(CONTEXT context, LogicalPlan plan, LogicalPlan.QueryBlock block, LimitNode node,
Stack<LogicalNode> stack) throws PlanningException {
stack.push(node);
RESULT result = visit(context, plan, block, node.getChild(), stack);
stack.pop();
return result;
}
@Override
public RESULT visitSort(CONTEXT context, LogicalPlan plan, LogicalPlan.QueryBlock block, SortNode node,
Stack<LogicalNode> stack) throws PlanningException {
stack.push(node);
RESULT result = visit(context, plan, block, node.getChild(), stack);
stack.pop();
return result;
}
@Override
public RESULT visitHaving(CONTEXT context, LogicalPlan plan, LogicalPlan.QueryBlock block, HavingNode node,
Stack<LogicalNode> stack) throws PlanningException {
stack.push(node);
RESULT result = visit(context, plan, block, node.getChild(), stack);
stack.pop();
return result;
}
@Override
public RESULT visitGroupBy(CONTEXT context, LogicalPlan plan, LogicalPlan.QueryBlock block, GroupbyNode node,
Stack<LogicalNode> stack) throws PlanningException {
stack.push(node);
RESULT result = visit(context, plan, block, node.getChild(), stack);
stack.pop();
return result;
}
@Override
public RESULT visitWindowAgg(CONTEXT context, LogicalPlan plan, LogicalPlan.QueryBlock block, WindowAggNode node,
Stack<LogicalNode> stack) throws PlanningException {
stack.push(node);
RESULT result = visit(context, plan, block, node.getChild(), stack);
stack.pop();
return result;
}
public RESULT visitDistinct(CONTEXT context, LogicalPlan plan, LogicalPlan.QueryBlock block, DistinctGroupbyNode node,
Stack<LogicalNode> stack) throws PlanningException {
stack.push(node);
RESULT result = visit(context, plan, block, node.getChild(), stack);
stack.pop();
return result;
}
@Override
public RESULT visitFilter(CONTEXT context, LogicalPlan plan, LogicalPlan.QueryBlock block, SelectionNode node,
Stack<LogicalNode> stack) throws PlanningException {
stack.push(node);
RESULT result = visit(context, plan, block, node.getChild(), stack);
stack.pop();
return result;
}
@Override
public RESULT visitJoin(CONTEXT context, LogicalPlan plan, LogicalPlan.QueryBlock block, JoinNode node,
Stack<LogicalNode> stack) throws PlanningException {
stack.push(node);
RESULT result = visit(context, plan, block, node.getLeftChild(), stack);
visit(context, plan, block, node.getRightChild(), stack);
stack.pop();
return result;
}
@Override
public RESULT visitUnion(CONTEXT context, LogicalPlan plan, LogicalPlan.QueryBlock block, UnionNode node,
Stack<LogicalNode> stack) throws PlanningException {
stack.push(node);
LogicalPlan.QueryBlock leftBlock = plan.getBlock(node.getLeftChild());
RESULT result = visit(context, plan, leftBlock, leftBlock.getRoot(), stack);
LogicalPlan.QueryBlock rightBlock = plan.getBlock(node.getRightChild());
visit(context, plan, rightBlock, rightBlock.getRoot(), stack);
stack.pop();
return result;
}
@Override
public RESULT visitExcept(CONTEXT context, LogicalPlan plan, LogicalPlan.QueryBlock block, ExceptNode node,
Stack<LogicalNode> stack) throws PlanningException {
stack.push(node);
RESULT result = visit(context, plan, block, node.getLeftChild(), stack);
visit(context, plan, block, node.getRightChild(), stack);
stack.pop();
return result;
}
@Override
public RESULT visitIntersect(CONTEXT context, LogicalPlan plan, LogicalPlan.QueryBlock block, IntersectNode node,
Stack<LogicalNode> stack) throws PlanningException {
stack.push(node);
RESULT result = visit(context, plan, block, node.getLeftChild(), stack);
visit(context, plan, block, node.getRightChild(), stack);
stack.pop();
return result;
}
@Override
public RESULT visitTableSubQuery(CONTEXT context, LogicalPlan plan, LogicalPlan.QueryBlock block,
TableSubQueryNode node, Stack<LogicalNode> stack) throws PlanningException {
stack.push(node);
LogicalPlan.QueryBlock childBlock = plan.getBlock(node.getSubQuery());
RESULT result = visit(context, plan, childBlock, childBlock.getRoot(), stack);
stack.pop();
return result;
}
@Override
public RESULT visitScan(CONTEXT context, LogicalPlan plan, LogicalPlan.QueryBlock block, ScanNode node,
Stack<LogicalNode> stack) throws PlanningException {
return null;
}
@Override
public RESULT visitPartitionedTableScan(CONTEXT context, LogicalPlan plan, LogicalPlan.QueryBlock block,
PartitionedTableScanNode node, Stack<LogicalNode> stack)
throws PlanningException {
return null;
}
@Override
public RESULT visitStoreTable(CONTEXT context, LogicalPlan plan, LogicalPlan.QueryBlock block, StoreTableNode node,
Stack<LogicalNode> stack) throws PlanningException {
stack.push(node);
RESULT result = visit(context, plan, block, node.getChild(), stack);
stack.pop();
return result;
}
@Override
public RESULT visitInsert(CONTEXT context, LogicalPlan plan, LogicalPlan.QueryBlock block, InsertNode node,
Stack<LogicalNode> stack) throws PlanningException {
stack.push(node);
RESULT result = visit(context, plan, block, node.getChild(), stack);
stack.pop();
return result;
}
@Override
public RESULT visitCreateDatabase(CONTEXT context, LogicalPlan plan, LogicalPlan.QueryBlock block,
CreateDatabaseNode node, Stack<LogicalNode> stack) throws PlanningException {
return null;
}
@Override
public RESULT visitDropDatabase(CONTEXT context, LogicalPlan plan, LogicalPlan.QueryBlock block, DropDatabaseNode node, Stack<LogicalNode> stack) throws PlanningException {
return null;
}
@Override
public RESULT visitCreateTable(CONTEXT context, LogicalPlan plan, LogicalPlan.QueryBlock block, CreateTableNode node,
Stack<LogicalNode> stack) throws PlanningException {
RESULT result = null;
stack.push(node);
if (node.hasSubQuery()) {
result = visit(context, plan, block, node.getChild(), stack);
}
stack.pop();
return result;
}
@Override
public RESULT visitDropTable(CONTEXT context, LogicalPlan plan, LogicalPlan.QueryBlock block, DropTableNode node,
Stack<LogicalNode> stack) {
return null;
}
@Override
public RESULT visitAlterTablespace(CONTEXT context, LogicalPlan plan, LogicalPlan.QueryBlock block,
AlterTablespaceNode node, Stack<LogicalNode> stack) throws PlanningException {
return null;
}
@Override
public RESULT visitAlterTable(CONTEXT context, LogicalPlan plan, LogicalPlan.QueryBlock block, AlterTableNode node,
Stack<LogicalNode> stack) {
return null;
}
@Override
public RESULT visitTruncateTable(CONTEXT context, LogicalPlan plan, LogicalPlan.QueryBlock block,
TruncateTableNode node, Stack<LogicalNode> stack) throws PlanningException {
return null;
}
}