use of org.apache.calcite.rel.RelShuttleImpl in project samza by apache.
the class QueryTranslator method translate.
/**
* Translate Calcite plan to Samza stream operators.
* @param relRoot Calcite plan in the form of {@link RelRoot}. RelRoot should not include the sink ({@link TableModify})
* @param outputSystemStream Sink associated with the Calcite plan.
* @param translatorContext Context maintained across translations.
* @param queryId query index of the sql statement corresponding to the Calcite plan in multi SQL statement scenario
* starting with index 0.
*/
public void translate(RelRoot relRoot, String outputSystemStream, TranslatorContext translatorContext, int queryId) {
final RelNode node = relRoot.project();
ScanTranslator scanTranslator = new ScanTranslator(sqlConfig.getSamzaRelConverters(), sqlConfig.getInputSystemStreamConfigBySource(), queryId);
/* update input metrics */
String queryLogicalId = String.format(TranslatorConstants.LOGSQLID_TEMPLATE, queryId);
opId = 0;
node.accept(new RelShuttleImpl() {
@Override
public RelNode visit(RelNode relNode) {
// There should never be a TableModify in the calcite plan.
Validate.isTrue(!(relNode instanceof TableModify));
return super.visit(relNode);
}
@Override
public RelNode visit(TableScan scan) {
RelNode node = super.visit(scan);
String logicalOpId = String.format(TranslatorConstants.LOGOPID_TEMPLATE, queryId, "scan", opId++);
scanTranslator.translate(scan, queryLogicalId, logicalOpId, translatorContext, systemDescriptors, inputMsgStreams);
return node;
}
@Override
public RelNode visit(LogicalFilter filter) {
RelNode node = visitChild(filter, 0, filter.getInput());
String logicalOpId = String.format(TranslatorConstants.LOGOPID_TEMPLATE, queryId, "filter", opId++);
new FilterTranslator(queryId).translate(filter, logicalOpId, translatorContext);
return node;
}
@Override
public RelNode visit(LogicalProject project) {
RelNode node = super.visit(project);
String logicalOpId = String.format(TranslatorConstants.LOGOPID_TEMPLATE, queryId, "project", opId++);
new ProjectTranslator(queryId).translate(project, logicalOpId, translatorContext);
return node;
}
@Override
public RelNode visit(LogicalJoin join) {
RelNode node = super.visit(join);
String logicalOpId = String.format(TranslatorConstants.LOGOPID_TEMPLATE, queryId, "join", opId++);
new JoinTranslator(logicalOpId, sqlConfig.getMetadataTopicPrefix(), queryId).translate(join, translatorContext);
return node;
}
@Override
public RelNode visit(LogicalAggregate aggregate) {
RelNode node = super.visit(aggregate);
String logicalOpId = String.format(TranslatorConstants.LOGOPID_TEMPLATE, queryId, "window", opId++);
new LogicalAggregateTranslator(logicalOpId, sqlConfig.getMetadataTopicPrefix()).translate(aggregate, translatorContext);
return node;
}
});
String logicalOpId = String.format(TranslatorConstants.LOGOPID_TEMPLATE, queryId, "insert", opId);
sendToOutputStream(queryLogicalId, logicalOpId, outputSystemStream, streamAppDescriptor, translatorContext, node, queryId);
}
use of org.apache.calcite.rel.RelShuttleImpl in project calcite by apache.
the class SqlToRelConverterExtendedTest method foo.
public static void foo(RelNode rel) {
// Convert rel tree to JSON.
final RelJsonWriter writer = new RelJsonWriter();
rel.explain(writer);
final String json = writer.asString();
// Find the schema. If there are no tables in the plan, we won't need one.
final RelOptSchema[] schemas = { null };
rel.accept(new RelShuttleImpl() {
@Override
public RelNode visit(TableScan scan) {
schemas[0] = scan.getTable().getRelOptSchema();
return super.visit(scan);
}
});
// Convert JSON back to rel tree.
Frameworks.withPlanner(new Frameworks.PlannerAction<Object>() {
public Object apply(RelOptCluster cluster, RelOptSchema relOptSchema, SchemaPlus rootSchema) {
final RelJsonReader reader = new RelJsonReader(cluster, schemas[0], rootSchema);
try {
RelNode x = reader.read(json);
} catch (IOException e) {
throw new RuntimeException(e);
}
return null;
}
});
}
use of org.apache.calcite.rel.RelShuttleImpl in project calcite by apache.
the class RelOptMaterialization method tryUseStar.
/**
* Converts a relational expression to one that uses a
* {@link org.apache.calcite.schema.impl.StarTable}.
*
* <p>The relational expression is already in leaf-join-form, per
* {@link #toLeafJoinForm(org.apache.calcite.rel.RelNode)}.
*
* @return Rewritten expression, or null if expression cannot be rewritten
* to use the star
*/
public static RelNode tryUseStar(RelNode rel, final RelOptTable starRelOptTable) {
final StarTable starTable = starRelOptTable.unwrap(StarTable.class);
assert starTable != null;
RelNode rel2 = rel.accept(new RelShuttleImpl() {
@Override
public RelNode visit(TableScan scan) {
RelOptTable relOptTable = scan.getTable();
final Table table = relOptTable.unwrap(Table.class);
if (table.equals(starTable.tables.get(0))) {
Mappings.TargetMapping mapping = Mappings.createShiftMapping(starRelOptTable.getRowType().getFieldCount(), 0, 0, relOptTable.getRowType().getFieldCount());
final RelOptCluster cluster = scan.getCluster();
final RelNode scan2 = starRelOptTable.toRel(RelOptUtil.getContext(cluster));
return RelOptUtil.createProject(scan2, Mappings.asList(mapping.inverse()));
}
return scan;
}
@Override
public RelNode visit(LogicalJoin join) {
for (; ; ) {
RelNode rel = super.visit(join);
if (rel == join || !(rel instanceof LogicalJoin)) {
return rel;
}
join = (LogicalJoin) rel;
final ProjectFilterTable left = ProjectFilterTable.of(join.getLeft());
if (left != null) {
final ProjectFilterTable right = ProjectFilterTable.of(join.getRight());
if (right != null) {
try {
match(left, right, join.getCluster());
} catch (Util.FoundOne e) {
return (RelNode) e.getNode();
}
}
}
}
}
/**
* Throws a {@link org.apache.calcite.util.Util.FoundOne} containing
* a {@link org.apache.calcite.rel.logical.LogicalTableScan} on
* success. (Yes, an exception for normal operation.)
*/
private void match(ProjectFilterTable left, ProjectFilterTable right, RelOptCluster cluster) {
final Mappings.TargetMapping leftMapping = left.mapping();
final Mappings.TargetMapping rightMapping = right.mapping();
final RelOptTable leftRelOptTable = left.getTable();
final Table leftTable = leftRelOptTable.unwrap(Table.class);
final int leftCount = leftRelOptTable.getRowType().getFieldCount();
final RelOptTable rightRelOptTable = right.getTable();
final Table rightTable = rightRelOptTable.unwrap(Table.class);
if (leftTable instanceof StarTable && ((StarTable) leftTable).tables.contains(rightTable)) {
final int offset = ((StarTable) leftTable).columnOffset(rightTable);
Mappings.TargetMapping mapping = Mappings.merge(leftMapping, Mappings.offsetTarget(Mappings.offsetSource(rightMapping, offset), leftMapping.getTargetCount()));
final RelNode project = RelOptUtil.createProject(LogicalTableScan.create(cluster, leftRelOptTable), Mappings.asList(mapping.inverse()));
final List<RexNode> conditions = Lists.newArrayList();
if (left.condition != null) {
conditions.add(left.condition);
}
if (right.condition != null) {
conditions.add(RexUtil.apply(mapping, RexUtil.shift(right.condition, offset)));
}
final RelNode filter = RelOptUtil.createFilter(project, conditions);
throw new Util.FoundOne(filter);
}
if (rightTable instanceof StarTable && ((StarTable) rightTable).tables.contains(leftTable)) {
final int offset = ((StarTable) rightTable).columnOffset(leftTable);
Mappings.TargetMapping mapping = Mappings.merge(Mappings.offsetSource(leftMapping, offset), Mappings.offsetTarget(rightMapping, leftCount));
final RelNode project = RelOptUtil.createProject(LogicalTableScan.create(cluster, rightRelOptTable), Mappings.asList(mapping.inverse()));
final List<RexNode> conditions = Lists.newArrayList();
if (left.condition != null) {
conditions.add(RexUtil.apply(mapping, RexUtil.shift(left.condition, offset)));
}
if (right.condition != null) {
conditions.add(RexUtil.apply(mapping, right.condition));
}
final RelNode filter = RelOptUtil.createFilter(project, conditions);
throw new Util.FoundOne(filter);
}
}
});
if (rel2 == rel) {
// No rewrite happened.
return null;
}
final Program program = Programs.hep(ImmutableList.of(ProjectFilterTransposeRule.INSTANCE, AggregateProjectMergeRule.INSTANCE, AggregateFilterTransposeRule.INSTANCE), false, DefaultRelMetadataProvider.INSTANCE);
return program.run(null, rel2, null, ImmutableList.<RelOptMaterialization>of(), ImmutableList.<RelOptLattice>of());
}
use of org.apache.calcite.rel.RelShuttleImpl in project drill by apache.
the class FindLimit0Visitor method addLimitOnTopOfLeafNodes.
public static DrillRel addLimitOnTopOfLeafNodes(final DrillRel rel) {
final Pointer<Boolean> isUnsupported = new Pointer<>(false);
// to visit unsupported functions
final RexShuttle unsupportedFunctionsVisitor = new RexShuttle() {
@Override
public RexNode visitCall(RexCall call) {
final SqlOperator operator = call.getOperator();
if (isUnsupportedScalarFunction(operator)) {
isUnsupported.value = true;
return call;
}
return super.visitCall(call);
}
};
// to visit unsupported operators
final RelShuttle unsupportedOperationsVisitor = new RelShuttleImpl() {
@Override
public RelNode visit(RelNode other) {
if (other instanceof DrillUnionRelBase) {
isUnsupported.value = true;
return other;
} else if (other instanceof DrillProjectRelBase) {
if (!isUnsupported.value) {
other.accept(unsupportedFunctionsVisitor);
}
if (isUnsupported.value) {
return other;
}
}
return super.visit(other);
}
};
rel.accept(unsupportedOperationsVisitor);
if (isUnsupported.value) {
return rel;
}
// to add LIMIT (0) on top of leaf nodes
final RelShuttle addLimitOnScanVisitor = new RelShuttleImpl() {
private RelNode addLimitAsParent(RelNode node) {
final RexBuilder builder = node.getCluster().getRexBuilder();
final RexLiteral offset = builder.makeExactLiteral(BigDecimal.ZERO);
final RexLiteral fetch = builder.makeExactLiteral(BigDecimal.ZERO);
return new DrillLimitRel(node.getCluster(), node.getTraitSet(), node, offset, fetch);
}
@Override
public RelNode visit(LogicalValues values) {
return addLimitAsParent(values);
}
@Override
public RelNode visit(TableScan scan) {
return addLimitAsParent(scan);
}
@Override
public RelNode visit(RelNode other) {
if (other.getInputs().isEmpty()) {
// leaf operator
return addLimitAsParent(other);
}
return super.visit(other);
}
};
return (DrillRel) rel.accept(addLimitOnScanVisitor);
}
use of org.apache.calcite.rel.RelShuttleImpl in project hazelcast by hazelcast.
the class CalciteSqlOptimizer method extractPermissions.
private List<Permission> extractPermissions(PhysicalRel physicalRel) {
List<Permission> permissions = new ArrayList<>();
physicalRel.accept(new RelShuttleImpl() {
@Override
public RelNode visit(TableScan scan) {
addPermissionForTable(scan.getTable(), ActionConstants.ACTION_READ);
return super.visit(scan);
}
@Override
public RelNode visit(RelNode other) {
addPermissionForTable(other.getTable(), ActionConstants.ACTION_PUT);
return super.visit(other);
}
private void addPermissionForTable(RelOptTable t, String action) {
if (t == null) {
return;
}
HazelcastTable table = t.unwrap(HazelcastTable.class);
if (table != null && table.getTarget() instanceof AbstractMapTable) {
String mapName = ((AbstractMapTable) table.getTarget()).getMapName();
permissions.add(new MapPermission(mapName, action));
}
}
});
return permissions;
}
Aggregations