blob: 46f4551bc739c069f0b998bb8bdc8e3c7524c85d [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.
*/
#ifndef UNIVPLAN_SRC_UNIVPLAN_COMMON_PLANNODE_WALKER_H_
#define UNIVPLAN_SRC_UNIVPLAN_COMMON_PLANNODE_WALKER_H_
#include "univplan/proto/universal-plan.pb.h"
#include "dbcommon/log/logger.h"
namespace univplan {
class PlanNodeWalkerContext {
public:
PlanNodeWalkerContext() {}
virtual ~PlanNodeWalkerContext() {}
};
class PlanNodeWalker {
public:
PlanNodeWalker() {}
virtual ~PlanNodeWalker() {}
virtual void walk(UnivPlanExprPoly *expr, PlanNodeWalkerContext *ctx) = 0;
// Walk all dependent expressions.
// @param expr Root expr
// @param walker Apply walker->walk() for checking each expression
// @param ctx Context for checking list
static void walkExpressionTree(UnivPlanExprPoly *expr, PlanNodeWalker *walker,
PlanNodeWalkerContext *ctx) {
// Call walkExpressionTree to check all containing "UnivPlanExprPoly".
// Pay attention to check the "optional UnivPlanExprPoly" exist before
// calling walkExpressionTree.
if (expr->has_var() || expr->has_val() || expr->has_param()) {
// do nothing
} else if (expr->has_aggref()) {
UnivPlanAggref *aggref = expr->mutable_aggref();
walkExpressionTree(aggref->mutable_args(), walker, ctx);
} else if (expr->has_funcexpr()) {
UnivPlanFuncExpr *funcExpr = expr->mutable_funcexpr();
walkExpressionTree(funcExpr->mutable_args(), walker, ctx);
} else if (expr->has_opexpr()) {
UnivPlanOpExpr *opExpr = expr->mutable_opexpr();
walkExpressionTree(opExpr->mutable_args(), walker, ctx);
} else if (expr->has_boolexpr()) {
UnivPlanBoolExpr *boolExpr = expr->mutable_boolexpr();
walkExpressionTree(boolExpr->mutable_args(), walker, ctx);
} else if (expr->has_nulltest()) {
UnivPlanNullTest *nullTest = expr->mutable_nulltest();
walkExpressionTree(nullTest->mutable_arg(), walker, ctx);
} else if (expr->has_booltest()) {
UnivPlanBooleanTest *boolTest = expr->mutable_booltest();
walkExpressionTree(boolTest->mutable_arg(), walker, ctx);
} else if (expr->has_targetentry()) {
UnivPlanTargetEntry *targetEntry = expr->mutable_targetentry();
walkExpressionTree(targetEntry->mutable_expression(), walker, ctx);
} else if (expr->has_caseexpr()) {
UnivPlanCaseExpr *caseexpr = expr->mutable_caseexpr();
walkExpressionTree(caseexpr->mutable_args(), walker, ctx);
walkExpressionTree(caseexpr->mutable_defresult(), walker, ctx);
} else if (expr->has_casewhen()) {
UnivPlanCaseWhen *casewhen = expr->mutable_casewhen();
walkExpressionTree(casewhen->mutable_expr(), walker, ctx);
walkExpressionTree(casewhen->mutable_result(), walker, ctx);
} else if (expr->has_subplan()) {
UnivPlanSubPlan *subplan = expr->mutable_subplan();
walkExpressionTree(subplan->mutable_args(), walker, ctx);
if (subplan->has_testexpr())
walkExpressionTree(subplan->mutable_testexpr(), walker, ctx);
} else if (expr->has_scalararrayopexpr()) {
UnivPlanScalarArrayOpExpr *scalarArrayOpExpr =
expr->mutable_scalararrayopexpr();
walkExpressionTree(scalarArrayOpExpr->mutable_args(), walker, ctx);
} else if (expr->has_coalesceexpr()) {
UnivPlanCoalesceExpr *coalesceExpr = expr->mutable_coalesceexpr();
walkExpressionTree(coalesceExpr->mutable_args(), walker, ctx);
} else if (expr->has_nullifexpr()) {
UnivPlanNullIfExpr *nullIfExpr = expr->mutable_nullifexpr();
walkExpressionTree(nullIfExpr->mutable_args(), walker, ctx);
} else if (expr->has_distinctexpr()) {
UnivPlanDistinctExpr *distinctExpr = expr->mutable_distinctexpr();
walkExpressionTree(distinctExpr->mutable_args(), walker, ctx);
} else {
LOG_ERROR(ERRCODE_INTERNAL_ERROR,
"PlanNodeUtil::expressionTreeWalker expr %d not supported",
expr->type());
}
walker->walk(expr, ctx);
}
static void walkExpressionTree(UnivPlanExprPolyList *exprs,
PlanNodeWalker *walker,
PlanNodeWalkerContext *ctx) {
for (int i = 0; i < exprs->size(); ++i) {
walkExpressionTree(exprs->Mutable(i), walker, ctx);
}
}
virtual void walk(UnivPlanPlanNodePoly *planNodePoly, PlanNodeWalker *walker,
PlanNodeWalkerContext *ctx) {}
static void walkPlanTree(UnivPlanPlanNodePoly *planNodePoly,
PlanNodeWalker *walker, PlanNodeWalkerContext *ctx) {
auto planNode = PlanNodeUtil::getMutablePlanNode(planNodePoly);
if (planNode->has_leftplan())
walkPlanTree(planNode->mutable_leftplan(), walker, ctx);
if (planNode->has_rightplan())
walkPlanTree(planNode->mutable_rightplan(), walker, ctx);
if (planNodePoly->has_append()) {
auto append = planNodePoly->mutable_append();
for (auto i = 0; i < append->appendplans_size(); i++)
walkPlanTree(append->mutable_appendplans(i), walker, ctx);
}
walker->walk(planNodePoly, walker, ctx);
}
};
} // namespace univplan
#endif // UNIVPLAN_SRC_UNIVPLAN_COMMON_PLANNODE_WALKER_H_