This is an automated email from the ASF dual-hosted git repository. caogaofei pushed a commit to branch beyyes/fix_sonar in repository https://gitbox.apache.org/repos/asf/iotdb.git
commit 4ad478acbda2f2f3a57801e1073de832c1c77851 Author: Beyyes <[email protected]> AuthorDate: Mon Jun 19 17:55:11 2023 +0800 fix sonar code smells in /mpp/plan/planner/OperatorTreeGenerator and mpp/plan/planner/SubPlanTypeExtractor --- .../db/mpp/plan/planner/OperatorTreeGenerator.java | 297 +++++++++++---------- .../db/mpp/plan/planner/SubPlanTypeExtractor.java | 2 + 2 files changed, 153 insertions(+), 146 deletions(-) diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/OperatorTreeGenerator.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/OperatorTreeGenerator.java index 9273acd3361..ba6c89f63d4 100644 --- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/OperatorTreeGenerator.java +++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/OperatorTreeGenerator.java @@ -16,6 +16,7 @@ * specific language governing permissions and limitations * under the License. */ + package org.apache.iotdb.db.mpp.plan.planner; import org.apache.iotdb.common.rpc.thrift.TEndPoint; @@ -247,7 +248,7 @@ import static org.apache.iotdb.db.mpp.execution.operator.AggregationUtil.calcula import static org.apache.iotdb.db.mpp.execution.operator.AggregationUtil.initTimeRangeIterator; import static org.apache.iotdb.db.mpp.plan.planner.plan.parameter.SeriesScanOptions.updateFilterUsingTTL; -/** This Visitor is responsible for transferring PlanNode Tree to Operator Tree */ +/** This Visitor is responsible for transferring PlanNode Tree to Operator Tree. */ public class OperatorTreeGenerator extends PlanVisitor<Operator, LocalExecutionPlanContext> { private static final MPPDataExchangeManager MPP_DATA_EXCHANGE_MANAGER = @@ -268,6 +269,8 @@ public class OperatorTreeGenerator extends PlanVisitor<Operator, LocalExecutionP private static final Comparator<Binary> DESC_BINARY_COMPARATOR = Comparator.reverseOrder(); + private static final String UNKNOWN_DATATYPE = "Unknown data type: "; + @Override public Operator visitPlan(PlanNode node, LocalExecutionPlanContext context) { throw new UnsupportedOperationException("should call the concrete visitXX() method"); @@ -275,30 +278,30 @@ public class OperatorTreeGenerator extends PlanVisitor<Operator, LocalExecutionP @Override public Operator visitSeriesScan(SeriesScanNode node, LocalExecutionPlanContext context) { - PartialPath seriesPath = node.getSeriesPath(); - - OperatorContext operatorContext = - context - .getDriverContext() - .addOperatorContext( - context.getNextOperatorId(), - node.getPlanNodeId(), - SeriesScanOperator.class.getSimpleName()); + SeriesScanOptions.Builder seriesScanOptionsBuilder = new SeriesScanOptions.Builder(); Filter timeFilter = node.getTimeFilter(); Filter valueFilter = node.getValueFilter(); - SeriesScanOptions.Builder seriesScanOptionsBuilder = new SeriesScanOptions.Builder(); if (timeFilter != null) { seriesScanOptionsBuilder.withGlobalTimeFilter(timeFilter.copy()); } if (valueFilter != null) { seriesScanOptionsBuilder.withQueryFilter(valueFilter.copy()); } + + PartialPath seriesPath = node.getSeriesPath(); seriesScanOptionsBuilder.withAllSensors( context.getAllSensors(seriesPath.getDevice(), seriesPath.getMeasurement())); seriesScanOptionsBuilder.withLimit(node.getLimit()); seriesScanOptionsBuilder.withOffset(node.getOffset()); + OperatorContext operatorContext = + context + .getDriverContext() + .addOperatorContext( + context.getNextOperatorId(), + node.getPlanNodeId(), + SeriesScanOperator.class.getSimpleName()); SeriesScanOperator seriesScanOperator = new SeriesScanOperator( operatorContext, @@ -317,19 +320,9 @@ public class OperatorTreeGenerator extends PlanVisitor<Operator, LocalExecutionP @Override public Operator visitAlignedSeriesScan( AlignedSeriesScanNode node, LocalExecutionPlanContext context) { - AlignedPath seriesPath = node.getAlignedPath(); - - OperatorContext operatorContext = - context - .getDriverContext() - .addOperatorContext( - context.getNextOperatorId(), - node.getPlanNodeId(), - AlignedSeriesScanOperator.class.getSimpleName()); - + SeriesScanOptions.Builder seriesScanOptionsBuilder = new SeriesScanOptions.Builder(); Filter timeFilter = node.getTimeFilter(); Filter valueFilter = node.getValueFilter(); - SeriesScanOptions.Builder seriesScanOptionsBuilder = new SeriesScanOptions.Builder(); if (timeFilter != null) { seriesScanOptionsBuilder.withGlobalTimeFilter(timeFilter.copy()); } @@ -338,8 +331,16 @@ public class OperatorTreeGenerator extends PlanVisitor<Operator, LocalExecutionP } seriesScanOptionsBuilder.withLimit(node.getLimit()); seriesScanOptionsBuilder.withOffset(node.getOffset()); + AlignedPath seriesPath = node.getAlignedPath(); seriesScanOptionsBuilder.withAllSensors(new HashSet<>(seriesPath.getMeasurementList())); + OperatorContext operatorContext = + context + .getDriverContext() + .addOperatorContext( + context.getNextOperatorId(), + node.getPlanNodeId(), + AlignedSeriesScanOperator.class.getSimpleName()); AlignedSeriesScanOperator seriesScanOperator = new AlignedSeriesScanOperator( operatorContext, @@ -362,14 +363,6 @@ public class OperatorTreeGenerator extends PlanVisitor<Operator, LocalExecutionP SeriesAggregationScanNode node, LocalExecutionPlanContext context) { PartialPath seriesPath = node.getSeriesPath(); boolean ascending = node.getScanOrder() == Ordering.ASC; - OperatorContext operatorContext = - context - .getDriverContext() - .addOperatorContext( - context.getNextOperatorId(), - node.getPlanNodeId(), - SeriesAggregationScanOperator.class.getSimpleName()); - List<AggregationDescriptor> aggregationDescriptors = node.getAggregationDescriptorList(); List<Aggregator> aggregators = new ArrayList<>(); aggregationDescriptors.forEach( @@ -403,6 +396,13 @@ public class OperatorTreeGenerator extends PlanVisitor<Operator, LocalExecutionP scanOptionsBuilder.withQueryFilter(valueFilter.copy()); } + OperatorContext operatorContext = + context + .getDriverContext() + .addOperatorContext( + context.getNextOperatorId(), + node.getPlanNodeId(), + SeriesAggregationScanOperator.class.getSimpleName()); SeriesAggregationScanOperator aggregateScanOperator = new SeriesAggregationScanOperator( node.getPlanNodeId(), @@ -427,13 +427,6 @@ public class OperatorTreeGenerator extends PlanVisitor<Operator, LocalExecutionP AlignedSeriesAggregationScanNode node, LocalExecutionPlanContext context) { AlignedPath seriesPath = node.getAlignedPath(); boolean ascending = node.getScanOrder() == Ordering.ASC; - OperatorContext operatorContext = - context - .getDriverContext() - .addOperatorContext( - context.getNextOperatorId(), - node.getPlanNodeId(), - AlignedSeriesAggregationScanOperator.class.getSimpleName()); List<Aggregator> aggregators = new ArrayList<>(); for (AggregationDescriptor descriptor : node.getAggregationDescriptorList()) { checkArgument( @@ -479,6 +472,13 @@ public class OperatorTreeGenerator extends PlanVisitor<Operator, LocalExecutionP scanOptionsBuilder.withQueryFilter(valueFilter.copy()); } + OperatorContext operatorContext = + context + .getDriverContext() + .addOperatorContext( + context.getNextOperatorId(), + node.getPlanNodeId(), + AlignedSeriesAggregationScanOperator.class.getSimpleName()); AlignedSeriesAggregationScanOperator seriesAggregationScanOperator = new AlignedSeriesAggregationScanOperator( node.getPlanNodeId(), @@ -781,14 +781,6 @@ public class OperatorTreeGenerator extends PlanVisitor<Operator, LocalExecutionP @Deprecated @Override public Operator visitDeviceMerge(DeviceMergeNode node, LocalExecutionPlanContext context) { - OperatorContext operatorContext = - context - .getDriverContext() - .addOperatorContext( - context.getNextOperatorId(), - node.getPlanNodeId(), - DeviceMergeOperator.class.getSimpleName()); - List<Operator> children = dealWithConsumeAllChildrenPipelineBreaker(node, context); List<TSDataType> dataTypes = getOutputColumnTypes(node, context.getTypeProvider()); TimeSelector selector = null; TimeComparator timeComparator = null; @@ -806,7 +798,15 @@ public class OperatorTreeGenerator extends PlanVisitor<Operator, LocalExecutionP } } + OperatorContext operatorContext = + context + .getDriverContext() + .addOperatorContext( + context.getNextOperatorId(), + node.getPlanNodeId(), + DeviceMergeOperator.class.getSimpleName()); context.getTimeSliceAllocator().recordExecutionWeight(operatorContext, 1); + List<Operator> children = dealWithConsumeAllChildrenPipelineBreaker(node, context); return new DeviceMergeOperator( operatorContext, node.getDevices(), children, dataTypes, selector, timeComparator); } @@ -936,7 +936,7 @@ public class OperatorTreeGenerator extends PlanVisitor<Operator, LocalExecutionP constantFill[i] = new DoubleConstantFill(literal.getDouble()); break; default: - throw new IllegalArgumentException("Unknown data type: " + inputDataTypes.get(i)); + throw new IllegalArgumentException(UNKNOWN_DATATYPE + inputDataTypes.get(i)); } } return constantFill; @@ -965,7 +965,7 @@ public class OperatorTreeGenerator extends PlanVisitor<Operator, LocalExecutionP previousFill[i] = new DoublePreviousFill(); break; default: - throw new IllegalArgumentException("Unknown data type: " + inputDataTypes.get(i)); + throw new IllegalArgumentException(UNKNOWN_DATATYPE + inputDataTypes.get(i)); } } return previousFill; @@ -992,7 +992,7 @@ public class OperatorTreeGenerator extends PlanVisitor<Operator, LocalExecutionP linearFill[i] = IDENTITY_LINEAR_FILL; break; default: - throw new IllegalArgumentException("Unknown data type: " + inputDataTypes.get(i)); + throw new IllegalArgumentException(UNKNOWN_DATATYPE + inputDataTypes.get(i)); } } return linearFill; @@ -1115,10 +1115,10 @@ public class OperatorTreeGenerator extends PlanVisitor<Operator, LocalExecutionP ExpressionTypeAnalyzer.analyzeExpression(expressionTypes, projectExpression); } - boolean hasNonMappableUDF = false; + boolean hasNonMappableUdf = false; for (Expression expression : projectExpressions) { if (!expression.isMappable(expressionTypes)) { - hasNonMappableUDF = true; + hasNonMappableUdf = true; break; } } @@ -1161,7 +1161,7 @@ public class OperatorTreeGenerator extends PlanVisitor<Operator, LocalExecutionP Map<Expression, ColumnTransformer> projectExpressionColumnTransformerMap = new HashMap<>(); // init project transformer when project expressions are all mappable - if (!hasNonMappableUDF) { + if (!hasNonMappableUdf) { // init project UDTFContext UDTFContext projectContext = new UDTFContext(node.getZoneId()); projectContext.constructUdfExecutors(projectExpressions); @@ -1194,11 +1194,11 @@ public class OperatorTreeGenerator extends PlanVisitor<Operator, LocalExecutionP commonTransformerList, projectLeafColumnTransformerList, projectOutputTransformerList, - hasNonMappableUDF, + hasNonMappableUdf, true); // Project expressions don't contain Non-Mappable UDF, TransformOperator is not needed - if (!hasNonMappableUDF) { + if (!hasNonMappableUdf) { return filter; } @@ -1326,9 +1326,7 @@ public class OperatorTreeGenerator extends PlanVisitor<Operator, LocalExecutionP .flatMap(Collection::stream) .filter(Objects::nonNull) .collect(Collectors.toList()); - long maxReturnSize = - calculateMaxAggregationResultSize( - aggregationDescriptors, timeRangeIterator, context.getTypeProvider()); + OperatorContext operatorContext = context .getDriverContext() @@ -1337,6 +1335,10 @@ public class OperatorTreeGenerator extends PlanVisitor<Operator, LocalExecutionP node.getPlanNodeId(), TagAggregationOperator.class.getSimpleName()); context.getTimeSliceAllocator().recordExecutionWeight(operatorContext, aggregatorCount); + long maxReturnSize = + calculateMaxAggregationResultSize( + aggregationDescriptors, timeRangeIterator, context.getTypeProvider()); + return new TagAggregationOperator( operatorContext, groups, groupedAggregators, children, maxReturnSize); } @@ -1595,7 +1597,6 @@ public class OperatorTreeGenerator extends PlanVisitor<Operator, LocalExecutionP @Override public Operator visitSort(SortNode node, LocalExecutionPlanContext context) { - Operator child = node.getChild().accept(this, context); OperatorContext operatorContext = context .getDriverContext() @@ -1629,6 +1630,8 @@ public class OperatorTreeGenerator extends PlanVisitor<Operator, LocalExecutionP context.getDriverContext().setHaveTmpFile(true); context.getDriverContext().getFragmentInstanceContext().setMayHaveTmpFile(true); + Operator child = node.getChild().accept(this, context); + return new SortOperator( operatorContext, child, @@ -1930,8 +1933,6 @@ public class OperatorTreeGenerator extends PlanVisitor<Operator, LocalExecutionP IdentitySinkOperator.class.getSimpleName()); context.getTimeSliceAllocator().recordExecutionWeight(operatorContext, 1); - List<Operator> children = dealWithConsumeChildrenOneByOneNode(node, context); - checkArgument( MPP_DATA_EXCHANGE_MANAGER != null, "MPP_DATA_EXCHANGE_MANAGER should not be null"); FragmentInstanceId localInstanceId = context.getInstanceContext().getId(); @@ -1947,6 +1948,7 @@ public class OperatorTreeGenerator extends PlanVisitor<Operator, LocalExecutionP sinkHandle.setMaxBytesCanReserve(context.getMaxBytesOneHandleCanReserve()); context.getDriverContext().setSink(sinkHandle); + List<Operator> children = dealWithConsumeChildrenOneByOneNode(node, context); return new IdentitySinkOperator(operatorContext, children, downStreamChannelIndex, sinkHandle); } @@ -2083,6 +2085,45 @@ public class OperatorTreeGenerator extends PlanVisitor<Operator, LocalExecutionP } } + private AlignedUpdateLastCacheOperator createAlignedUpdateLastCacheOperator( + AlignedLastQueryScanNode node, AlignedPath unCachedPath, LocalExecutionPlanContext context) { + AlignedSeriesAggregationScanOperator lastQueryScan = + createLastQueryScanOperator(node, unCachedPath, context); + + if (node.getOutputViewPath() == null) { + OperatorContext operatorContext = + context + .getDriverContext() + .addOperatorContext( + context.getNextOperatorId(), + node.getPlanNodeId(), + AlignedUpdateLastCacheOperator.class.getSimpleName()); + context.getTimeSliceAllocator().recordExecutionWeight(operatorContext, 1); + return new AlignedUpdateLastCacheOperator( + operatorContext, + lastQueryScan, + unCachedPath, + DATA_NODE_SCHEMA_CACHE, + context.isNeedUpdateLastCache()); + } else { + OperatorContext operatorContext = + context + .getDriverContext() + .addOperatorContext( + context.getNextOperatorId(), + node.getPlanNodeId(), + AlignedUpdateViewPathLastCacheOperator.class.getSimpleName()); + context.getTimeSliceAllocator().recordExecutionWeight(operatorContext, 1); + return new AlignedUpdateViewPathLastCacheOperator( + operatorContext, + lastQueryScan, + unCachedPath, + DATA_NODE_SCHEMA_CACHE, + context.isNeedUpdateLastCache(), + node.getOutputViewPath()); + } + } + private SeriesAggregationScanOperator createLastQueryScanOperator( LastQueryScanNode node, LocalExecutionPlanContext context) { MeasurementPath seriesPath = node.getSeriesPath(); @@ -2124,6 +2165,49 @@ public class OperatorTreeGenerator extends PlanVisitor<Operator, LocalExecutionP return seriesAggregationScanOperator; } + private AlignedSeriesAggregationScanOperator createLastQueryScanOperator( + AlignedLastQueryScanNode node, AlignedPath unCachedPath, LocalExecutionPlanContext context) { + // last_time, last_value + List<Aggregator> aggregators = new ArrayList<>(); + for (int i = 0; i < unCachedPath.getMeasurementList().size(); i++) { + aggregators.addAll( + LastQueryUtil.createAggregators(unCachedPath.getSchemaList().get(i).getType(), i)); + } + ITimeRangeIterator timeRangeIterator = initTimeRangeIterator(null, false, false); + long maxReturnSize = calculateMaxAggregationResultSizeForLastQuery(aggregators, unCachedPath); + + Filter timeFilter = context.getLastQueryTimeFilter(); + SeriesScanOptions.Builder scanOptionsBuilder = new SeriesScanOptions.Builder(); + scanOptionsBuilder.withAllSensors(new HashSet<>(unCachedPath.getMeasurementList())); + if (timeFilter != null) { + scanOptionsBuilder.withGlobalTimeFilter(timeFilter.copy()); + } + + OperatorContext operatorContext = + context + .getDriverContext() + .addOperatorContext( + context.getNextOperatorId(), + node.getPlanNodeId(), + AlignedSeriesAggregationScanOperator.class.getSimpleName()); + AlignedSeriesAggregationScanOperator seriesAggregationScanOperator = + new AlignedSeriesAggregationScanOperator( + node.getPlanNodeId(), + unCachedPath, + Ordering.DESC, + scanOptionsBuilder.build(), + operatorContext, + aggregators, + timeRangeIterator, + null, + maxReturnSize); + ((DataDriverContext) context.getDriverContext()) + .addSourceOperator(seriesAggregationScanOperator); + ((DataDriverContext) context.getDriverContext()).addPath(unCachedPath); + context.getTimeSliceAllocator().recordExecutionWeight(operatorContext, aggregators.size()); + return seriesAggregationScanOperator; + } + @Override public Operator visitAlignedLastQueryScan( AlignedLastQueryScanNode node, LocalExecutionPlanContext context) { @@ -2167,89 +2251,6 @@ public class OperatorTreeGenerator extends PlanVisitor<Operator, LocalExecutionP } } - private AlignedUpdateLastCacheOperator createAlignedUpdateLastCacheOperator( - AlignedLastQueryScanNode node, AlignedPath unCachedPath, LocalExecutionPlanContext context) { - AlignedSeriesAggregationScanOperator lastQueryScan = - createLastQueryScanOperator(node, unCachedPath, context); - - if (node.getOutputViewPath() == null) { - OperatorContext operatorContext = - context - .getDriverContext() - .addOperatorContext( - context.getNextOperatorId(), - node.getPlanNodeId(), - AlignedUpdateLastCacheOperator.class.getSimpleName()); - context.getTimeSliceAllocator().recordExecutionWeight(operatorContext, 1); - return new AlignedUpdateLastCacheOperator( - operatorContext, - lastQueryScan, - unCachedPath, - DATA_NODE_SCHEMA_CACHE, - context.isNeedUpdateLastCache()); - } else { - OperatorContext operatorContext = - context - .getDriverContext() - .addOperatorContext( - context.getNextOperatorId(), - node.getPlanNodeId(), - AlignedUpdateViewPathLastCacheOperator.class.getSimpleName()); - context.getTimeSliceAllocator().recordExecutionWeight(operatorContext, 1); - return new AlignedUpdateViewPathLastCacheOperator( - operatorContext, - lastQueryScan, - unCachedPath, - DATA_NODE_SCHEMA_CACHE, - context.isNeedUpdateLastCache(), - node.getOutputViewPath()); - } - } - - private AlignedSeriesAggregationScanOperator createLastQueryScanOperator( - AlignedLastQueryScanNode node, AlignedPath unCachedPath, LocalExecutionPlanContext context) { - OperatorContext operatorContext = - context - .getDriverContext() - .addOperatorContext( - context.getNextOperatorId(), - node.getPlanNodeId(), - AlignedSeriesAggregationScanOperator.class.getSimpleName()); - - // last_time, last_value - List<Aggregator> aggregators = new ArrayList<>(); - for (int i = 0; i < unCachedPath.getMeasurementList().size(); i++) { - aggregators.addAll( - LastQueryUtil.createAggregators(unCachedPath.getSchemaList().get(i).getType(), i)); - } - ITimeRangeIterator timeRangeIterator = initTimeRangeIterator(null, false, false); - long maxReturnSize = calculateMaxAggregationResultSizeForLastQuery(aggregators, unCachedPath); - - Filter timeFilter = context.getLastQueryTimeFilter(); - SeriesScanOptions.Builder scanOptionsBuilder = new SeriesScanOptions.Builder(); - scanOptionsBuilder.withAllSensors(new HashSet<>(unCachedPath.getMeasurementList())); - if (timeFilter != null) { - scanOptionsBuilder.withGlobalTimeFilter(timeFilter.copy()); - } - - AlignedSeriesAggregationScanOperator seriesAggregationScanOperator = - new AlignedSeriesAggregationScanOperator( - node.getPlanNodeId(), - unCachedPath, - Ordering.DESC, - scanOptionsBuilder.build(), - operatorContext, - aggregators, - timeRangeIterator, - null, - maxReturnSize); - ((DataDriverContext) context.getDriverContext()) - .addSourceOperator(seriesAggregationScanOperator); - ((DataDriverContext) context.getDriverContext()).addPath(unCachedPath); - context.getTimeSliceAllocator().recordExecutionWeight(operatorContext, aggregators.size()); - return seriesAggregationScanOperator; - } - @Override public Operator visitLastQuery(LastQueryNode node, LocalExecutionPlanContext context) { @@ -2450,7 +2451,8 @@ public class OperatorTreeGenerator extends PlanVisitor<Operator, LocalExecutionP // Keep it since we may change the structure of origin children nodes List<PlanNode> afterwardsNodes = new ArrayList<>(); // 1. Calculate localChildren size - int localChildrenSize = 0, firstChildIndex = -1; + int localChildrenSize = 0; + int firstChildIndex = -1; for (int i = 0; i < node.getChildren().size(); i++) { if (!(node.getChildren().get(i) instanceof ExchangeNode)) { localChildrenSize++; @@ -2497,7 +2499,8 @@ public class OperatorTreeGenerator extends PlanVisitor<Operator, LocalExecutionP getChildNumInEachPipeline( node.getChildren(), localChildrenSize, context.getDegreeOfParallelism()); int childGroupNum = Math.min(context.getDegreeOfParallelism(), localChildrenSize); - int startIndex, endIndex = firstChildIndex; + int startIndex; + int endIndex = firstChildIndex; for (int i = 0; i < childGroupNum; i++) { startIndex = endIndex; endIndex += childNumInEachPipeline[i]; @@ -2621,8 +2624,10 @@ public class OperatorTreeGenerator extends PlanVisitor<Operator, LocalExecutionP } else { List<Integer> childPipelineNums = new ArrayList<>(); List<Integer> childExchangeNums = new ArrayList<>(); - int sumOfChildPipelines = 0, sumOfChildExchangeNums = 0; - int dependencyChildNode = 0, dependencyPipeId = 0; + int sumOfChildPipelines = 0; + int sumOfChildExchangeNums = 0; + int dependencyChildNode = 0; + int dependencyPipeId = 0; for (PlanNode childNode : node.getChildren()) { if (childNode instanceof ExchangeNode) { Operator childOperation = childNode.accept(this, context); diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/SubPlanTypeExtractor.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/SubPlanTypeExtractor.java index 0ead6cd7b59..7f194e03d80 100644 --- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/SubPlanTypeExtractor.java +++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/SubPlanTypeExtractor.java @@ -41,6 +41,8 @@ import java.util.stream.Stream; public class SubPlanTypeExtractor { + private SubPlanTypeExtractor() {} + public static TypeProvider extractor(PlanNode root, TypeProvider allTypes) { TypeProvider typeProvider = new TypeProvider(); root.accept(new Visitor(typeProvider, allTypes), null);
