@Override
  public Optional<PlanNode> visitDeleteData(
      final DeleteDataNode node, final IoTDBTreePattern pattern) {
    final List<MeasurementPath> intersectedPaths =
        node.getPathList().stream()
            .map(pattern::getIntersection)
            .flatMap(Collection::stream)
            .distinct()
            .map(d -> (MeasurementPath) d)
            .collect(Collectors.toList());
    return !intersectedPaths.isEmpty()
        ? Optional.of(
            new DeleteDataNode(
                node.getPlanNodeId(),
                intersectedPaths,
                node.getDeleteStartTime(),
                node.getDeleteEndTime()))
        : Optional.empty();
  }
The {@link PipePlanTreePatternParseVisitor} will transform the schema {@link PlanNode}s using
{@link IoTDBTreePattern}. Rule:

<p>1. All patterns in the output {@link PlanNode} will be the intersection of the original {@link
PlanNode}'s patterns and the given {@link IoTDBTreePattern}.

<p>2. If a pattern does not intersect with the {@link IoTDBTreePattern}, it's dropped.

<p>3. If all the patterns in the {@link PlanNode} is dropped, the {@link PlanNode} is dropped.

<p>4. The output {@link PlanNode} shall be a copied form of the original one because the original
one is used in the {@link PipeSchemaRegionWritePlanEvent} in {@link SchemaRegionListeningQueue}.
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/extractor/schemaregion/PipePlanTreePatternParseVisitor.java