use of org.apache.calcite.rel.RelNode in project drill by apache.
the class DefaultSqlHandler method transform.
/**
* Transform RelNode to a new RelNode, targeting the provided set of traits. Also will log the outcome if asked.
*
* @param plannerType
* The type of Planner to use.
* @param phase
* The transformation phase we're running.
* @param input
* The origianl RelNode
* @param targetTraits
* The traits we are targeting for output.
* @param log
* Whether to log the planning phase.
* @return The transformed relnode.
*/
protected RelNode transform(PlannerType plannerType, PlannerPhase phase, RelNode input, RelTraitSet targetTraits, boolean log) {
final Stopwatch watch = Stopwatch.createStarted();
final RuleSet rules = config.getRules(phase);
final RelTraitSet toTraits = targetTraits.simplify();
final RelNode output;
switch(plannerType) {
case HEP_BOTTOM_UP:
case HEP:
{
final HepProgramBuilder hepPgmBldr = new HepProgramBuilder();
if (plannerType == PlannerType.HEP_BOTTOM_UP) {
hepPgmBldr.addMatchOrder(HepMatchOrder.BOTTOM_UP);
}
for (RelOptRule rule : rules) {
hepPgmBldr.addRuleInstance(rule);
}
final HepPlanner planner = new HepPlanner(hepPgmBldr.build(), context.getPlannerSettings());
JaninoRelMetadataProvider relMetadataProvider = JaninoRelMetadataProvider.of(DrillDefaultRelMetadataProvider.INSTANCE);
RelMetadataQuery.THREAD_PROVIDERS.set(relMetadataProvider);
// Modify RelMetaProvider for every RelNode in the SQL operator Rel tree.
input.accept(new MetaDataProviderModifier(relMetadataProvider));
planner.setRoot(input);
if (!input.getTraitSet().equals(targetTraits)) {
planner.changeTraits(input, toTraits);
}
output = planner.findBestExp();
break;
}
case VOLCANO:
default:
{
// as weird as it seems, the cluster's only planner is the volcano planner.
final RelOptPlanner planner = input.getCluster().getPlanner();
final Program program = Programs.of(rules);
Preconditions.checkArgument(planner instanceof VolcanoPlanner, "Cluster is expected to be constructed using VolcanoPlanner. Was actually of type %s.", planner.getClass().getName());
output = program.run(planner, input, toTraits);
break;
}
}
if (log) {
log(plannerType, phase, output, logger, watch);
}
return output;
}
use of org.apache.calcite.rel.RelNode in project drill by apache.
the class DefaultSqlHandler method validateAndConvert.
protected ConvertedRelNode validateAndConvert(SqlNode sqlNode) throws ForemanSetupException, RelConversionException, ValidationException {
final SqlNode rewrittenSqlNode = rewrite(sqlNode);
final TypedSqlNode validatedTypedSqlNode = validateNode(rewrittenSqlNode);
final SqlNode validated = validatedTypedSqlNode.getSqlNode();
RelNode rel = convertToRel(validated);
rel = preprocessNode(rel);
return new ConvertedRelNode(rel, validatedTypedSqlNode.getType());
}
use of org.apache.calcite.rel.RelNode in project drill by apache.
the class DefaultSqlHandler method getPlan.
@Override
public PhysicalPlan getPlan(SqlNode sqlNode) throws ValidationException, RelConversionException, IOException, ForemanSetupException {
final ConvertedRelNode convertedRelNode = validateAndConvert(sqlNode);
final RelDataType validatedRowType = convertedRelNode.getValidatedRowType();
final RelNode queryRelNode = convertedRelNode.getConvertedNode();
final DrillRel drel = convertToDrel(queryRelNode, validatedRowType);
final Prel prel = convertToPrel(drel);
logAndSetTextPlan("Drill Physical", prel, logger);
final PhysicalOperator pop = convertToPop(prel);
final PhysicalPlan plan = convertToPlan(pop);
log("Drill Plan", plan, logger);
return plan;
}
use of org.apache.calcite.rel.RelNode in project drill by apache.
the class JoinUtils method isScalarSubquery.
/**
* Utility method to check if a subquery (represented by its root RelNode) is provably scalar. Currently
* only aggregates with no group-by are considered scalar. In the future, this method should be generalized
* to include more cases and reconciled with Calcite's notion of scalar.
* @param root The root RelNode to be examined
* @return True if the root rel or its descendant is scalar, False otherwise
*/
public static boolean isScalarSubquery(RelNode root) {
DrillAggregateRel agg = null;
RelNode currentrel = root;
while (agg == null && currentrel != null) {
if (currentrel instanceof DrillAggregateRel) {
agg = (DrillAggregateRel) currentrel;
} else if (currentrel instanceof RelSubset) {
currentrel = ((RelSubset) currentrel).getBest();
} else if (currentrel.getInputs().size() == 1) {
// If the rel is not an aggregate or RelSubset, but is a single-input rel (could be Project,
// Filter, Sort etc.), check its input
currentrel = currentrel.getInput(0);
} else {
break;
}
}
if (agg != null) {
if (agg.getGroupSet().isEmpty()) {
return true;
}
}
return false;
}
use of org.apache.calcite.rel.RelNode in project drill by apache.
the class JoinUtils method checkCartesianJoin.
/**
* Check if the given RelNode contains any Cartesian join.
* Return true if find one. Otherwise, return false.
*
* @param relNode the RelNode to be inspected.
* @param leftKeys a list used for the left input into the join which has
* equi-join keys. It can be empty or not (but not null),
* this method will clear this list before using it.
* @param rightKeys a list used for the right input into the join which has
* equi-join keys. It can be empty or not (but not null),
* this method will clear this list before using it.
* @param filterNulls The join key positions for which null values will not
* match.
* @return Return true if the given relNode contains Cartesian join.
* Otherwise, return false
*/
public static boolean checkCartesianJoin(RelNode relNode, List<Integer> leftKeys, List<Integer> rightKeys, List<Boolean> filterNulls) {
if (relNode instanceof Join) {
leftKeys.clear();
rightKeys.clear();
Join joinRel = (Join) relNode;
RelNode left = joinRel.getLeft();
RelNode right = joinRel.getRight();
RexNode remaining = RelOptUtil.splitJoinCondition(left, right, joinRel.getCondition(), leftKeys, rightKeys, filterNulls);
if (joinRel.getJoinType() == JoinRelType.INNER) {
if (leftKeys.isEmpty() || rightKeys.isEmpty()) {
return true;
}
} else {
if (!remaining.isAlwaysTrue() || leftKeys.isEmpty() || rightKeys.isEmpty()) {
return true;
}
}
}
for (RelNode child : relNode.getInputs()) {
if (checkCartesianJoin(child, leftKeys, rightKeys, filterNulls)) {
return true;
}
}
return false;
}
Aggregations