@Override protected Optional<PlanNode> pushDownProjectOff(PlanNodeIdAllocator idAllocator, TableScanNode tableScanNode, Set<Symbol> referencedOutputs) { return Optional.of( new TableScanNode( tableScanNode.getId(), tableScanNode.getTable(), filteredCopy(tableScanNode.getOutputSymbols(), referencedOutputs::contains), filterKeys(tableScanNode.getAssignments(), referencedOutputs::contains), tableScanNode.getLayout(), tableScanNode.getCurrentConstraint(), tableScanNode.getEnforcedConstraint())); } }
@Override public Void visitTableScan(TableScanNode node, Void context) { TableHandle tableHandle = node.getTable(); Set<Column> columns = new HashSet<>(); for (ColumnHandle columnHandle : node.getAssignments().values()) { columns.add(createColumn(metadata.getColumnMetadata(session, tableHandle, columnHandle))); } inputs.add(createInput(metadata.getTableMetadata(session, tableHandle), node.getLayout(), columns)); return null; }
@Override public Map<PlanNodeId, SplitSource> visitTableScan(TableScanNode node, Void context) { // get dataSource for table SplitSource splitSource = splitManager.getSplits( session, node.getLayout().get(), stageExecutionDescriptor.isScanGroupedExecution(node.getId()) ? GROUPED_SCHEDULING : UNGROUPED_SCHEDULING); splitSources.add(splitSource); return ImmutableMap.of(node.getId(), splitSource); }
TupleDomain<ColumnHandle> originalEnforcedConstraint = scan.getEnforcedConstraint(); handle, new Constraint<>(originalEnforcedConstraint), Optional.of(ImmutableSet.copyOf(scan.getAssignments().values()))); verify(layouts.size() == 1, "Expected exactly one layout for delete"); TableLayoutResult layoutResult = Iterables.getOnlyElement(layouts); return new TableScanNode( scan.getId(), handle, scan.getOutputSymbols(), scan.getAssignments(), Optional.of(layoutResult.getLayout().getHandle()), layoutResult.getLayout().getPredicate(),
.transform(node.getAssignments()::get) .intersect(node.getEnforcedConstraint()); checkState(node.getOutputSymbols().containsAll(context.getLookupSymbols())); .map(node.getAssignments()::get) .collect(toImmutableSet()); Set<ColumnHandle> outputColumns = node.getOutputSymbols().stream().map(node.getAssignments()::get).collect(toImmutableSet()); Optional<ResolvedIndex> optionalResolvedIndex = metadata.resolveIndex(session, node.getTable(), lookupColumns, outputColumns, simplifiedConstraint); if (!optionalResolvedIndex.isPresent()) { Map<ColumnHandle, Symbol> inverseAssignments = ImmutableBiMap.copyOf(node.getAssignments()).inverse(); node.getTable(), node.getLayout(), context.getLookupSymbols(), node.getOutputSymbols(), node.getAssignments(), simplifiedConstraint);
private void printTableScanInfo(TableScanNode node, int indent) TableHandle table = node.getTable(); if (node.getLayout().isPresent()) { ConnectorTableLayoutHandle layout = node.getLayout().get().getConnectorHandle(); if (!table.getConnectorHandle().toString().equals(layout.toString())) { print(indent + 2, "LAYOUT: %s", layout); TupleDomain<ColumnHandle> predicate = node.getCurrentConstraint(); if (predicate.isNone()) { print(indent + 2, ":: NONE"); for (Map.Entry<Symbol, ColumnHandle> assignment : node.getAssignments().entrySet()) { ColumnHandle column = assignment.getValue(); print(indent + 2, "%s := %s", assignment.getKey(), column); Set<ColumnHandle> outputs = ImmutableSet.copyOf(node.getAssignments().values());
@Override public StreamProperties visitTableScan(TableScanNode node, List<StreamProperties> inputProperties) { checkArgument(node.getLayout().isPresent(), "table layout has not yet been chosen"); TableLayout layout = metadata.getLayout(session, node.getLayout().get()); Map<ColumnHandle, Symbol> assignments = ImmutableBiMap.copyOf(node.getAssignments()).inverse(); // Globally constant assignments Set<ColumnHandle> constants = new HashSet<>(); extractFixedValues(node.getCurrentConstraint()).orElse(ImmutableMap.of()) .entrySet().stream() .filter(entry -> !entry.getValue().isNull()) // TODO consider allowing nulls .forEach(entry -> constants.add(entry.getKey())); Optional<Set<Symbol>> streamPartitionSymbols = layout.getStreamPartitioningColumns() .flatMap(columns -> getNonConstantSymbols(columns, assignments, constants)); // if we are partitioned on empty set, we must say multiple of unknown partitioning, because // the connector does not guarantee a single split in this case (since it might not understand // that the value is a constant). if (streamPartitionSymbols.isPresent() && streamPartitionSymbols.get().isEmpty()) { return new StreamProperties(MULTIPLE, Optional.empty(), false); } return new StreamProperties(MULTIPLE, streamPartitionSymbols, false); }
@Override public Void visitTableScan(TableScanNode node, IoPlanBuilder context) { TableMetadata tableMetadata = metadata.getTableMetadata(session, node.getTable()); context.addInputTableColumnInfo(new IoPlan.TableColumnInfo( new CatalogSchemaTableName( tableMetadata.getConnectorId().getCatalogName(), tableMetadata.getTable().getSchemaName(), tableMetadata.getTable().getTableName()), parseConstraints(node.getTable(), node.getCurrentConstraint()))); return null; }
@Override protected Optional<PlanNodeStatsEstimate> doCalculate(TableScanNode node, StatsProvider sourceStats, Lookup lookup, Session session, TypeProvider types) { // TODO Construct predicate like AddExchanges's LayoutConstraintEvaluator Constraint<ColumnHandle> constraint = new Constraint<>(node.getCurrentConstraint()); TableStatistics tableStatistics = metadata.getTableStatistics(session, node.getTable(), constraint); Map<Symbol, SymbolStatsEstimate> outputSymbolStats = new HashMap<>(); for (Map.Entry<Symbol, ColumnHandle> entry : node.getAssignments().entrySet()) { Symbol symbol = entry.getKey(); Optional<ColumnStatistics> columnStatistics = Optional.ofNullable(tableStatistics.getColumnStatistics().get(entry.getValue())); outputSymbolStats.put(symbol, columnStatistics.map(statistics -> toSymbolStatistics(tableStatistics, statistics)).orElse(SymbolStatsEstimate.unknown())); } return Optional.of(PlanNodeStatsEstimate.builder() .setOutputRowCount(tableStatistics.getRowCount().getValue()) .addSymbolStatistics(outputSymbolStats) .build()); }
@Override public Void visitTableScan(TableScanNode node, Integer indent) { TableHandle table = node.getTable(); if (stageExecutionStrategy.isPresent()) { print(indent, "- TableScan[%s, grouped = %s] => [%s]", table, stageExecutionStrategy.get().isGroupedExecution(node.getId()), formatOutputs(node.getOutputSymbols())); } else { print(indent, "- TableScan[%s] => [%s]", table, formatOutputs(node.getOutputSymbols())); } printPlanNodesStatsAndCost(indent + 2, node); printStats(indent + 2, node.getId()); printTableScanInfo(node, indent); return null; }
public TableScanNode tableScan( TableHandle tableHandle, List<Symbol> symbols, Map<Symbol, ColumnHandle> assignments, Optional<TableLayoutHandle> tableLayout, TupleDomain<ColumnHandle> currentConstraint, TupleDomain<ColumnHandle> enforcedConstraint) { return new TableScanNode( idAllocator.getNextId(), tableHandle, symbols, assignments, tableLayout, currentConstraint, enforcedConstraint); }
@Override public PhysicalOperation visitTableScan(TableScanNode node, LocalExecutionPlanContext context) { List<ColumnHandle> columns = new ArrayList<>(); for (Symbol symbol : node.getOutputSymbols()) { columns.add(node.getAssignments().get(symbol)); } OperatorFactory operatorFactory = new TableScanOperatorFactory(context.getNextOperatorId(), node.getId(), pageSourceProvider, columns); return new PhysicalOperation(operatorFactory, makeLayout(node), context, stageExecutionStrategy.isGroupedExecution(node.getId()) ? GROUPED_EXECUTION : UNGROUPED_EXECUTION); }
public boolean hasAllOutputs(TableScanNode node) { if (!layout.getColumns().isPresent()) { return true; } Set<ColumnHandle> columns = ImmutableSet.copyOf(layout.getColumns().get()); List<ColumnHandle> nodeColumnHandles = node.getOutputSymbols().stream() .map(node.getAssignments()::get) .collect(toImmutableList()); return columns.containsAll(nodeColumnHandles); }
@Override public PlanNode visitTableFinish(TableFinishNode node, RewriteContext<Void> context) { Optional<DeleteNode> delete = findNode(node.getSource(), DeleteNode.class); if (!delete.isPresent()) { return context.defaultRewrite(node); } Optional<TableScanNode> tableScan = findNode(delete.get().getSource(), TableScanNode.class); if (!tableScan.isPresent()) { return context.defaultRewrite(node); } TableScanNode tableScanNode = tableScan.get(); if (!metadata.supportsMetadataDelete(session, tableScanNode.getTable(), tableScanNode.getLayout().get())) { return context.defaultRewrite(node); } return new MetadataDeleteNode(idAllocator.getNextId(), delete.get().getTarget(), Iterables.getOnlyElement(node.getOutputSymbols()), tableScanNode.getLayout().get()); }
private boolean arePlansSame(FilterNode filter, TableScanNode tableScan, PlanNode rewritten) { if (!(rewritten instanceof FilterNode)) { return false; } FilterNode rewrittenFilter = (FilterNode) rewritten; if (!Objects.equals(filter.getPredicate(), rewrittenFilter.getPredicate())) { return false; } if (!(rewrittenFilter.getSource() instanceof TableScanNode)) { return false; } TableScanNode rewrittenTableScan = (TableScanNode) rewrittenFilter.getSource(); if (!tableScan.getLayout().isPresent() && rewrittenTableScan.getLayout().isPresent()) { return false; } return Objects.equals(tableScan.getCurrentConstraint(), rewrittenTableScan.getCurrentConstraint()) && Objects.equals(tableScan.getEnforcedConstraint(), rewrittenTableScan.getEnforcedConstraint()); } }
@Override public Optional<Symbol> getAssignedSymbol(PlanNode node, Session session, Metadata metadata, SymbolAliases symbolAliases) { TableHandle tableHandle; Map<Symbol, ColumnHandle> assignments; if (node instanceof TableScanNode) { TableScanNode tableScanNode = (TableScanNode) node; tableHandle = tableScanNode.getTable(); assignments = tableScanNode.getAssignments(); } else if (node instanceof IndexSourceNode) { IndexSourceNode indexSourceNode = (IndexSourceNode) node; tableHandle = indexSourceNode.getTableHandle(); assignments = indexSourceNode.getAssignments(); } else { return Optional.empty(); } TableMetadata tableMetadata = metadata.getTableMetadata(session, tableHandle); String actualTableName = tableMetadata.getTable().getTableName(); // Wrong table -> doesn't match. if (!tableName.equalsIgnoreCase(actualTableName)) { return Optional.empty(); } Optional<ColumnHandle> columnHandle = getColumnHandle(tableHandle, session, metadata); checkState(columnHandle.isPresent(), format("Table %s doesn't have column %s. Typo in test?", tableName, columnName)); return getAssignedSymbol(assignments, columnHandle.get()); }
@Override public Expression visitTableScan(TableScanNode node, Void context) { Map<ColumnHandle, Symbol> assignments = ImmutableBiMap.copyOf(node.getAssignments()).inverse(); return domainTranslator.toPredicate(node.getCurrentConstraint().simplify().transform(assignments::get)); }
@Override public Void visitTableScan(TableScanNode node, Consumer<PlanNodeId> schedulingOrder) { schedulingOrder.accept(node.getId()); return null; } }
TableScanNode tableScan = new TableScanNode( tableScanNodeId, new TableHandle(CONNECTOR_ID, new TestingTableHandle()), ImmutableList.of(), ImmutableList.<Symbol>builder() .addAll(tableScan.getOutputSymbols()) .addAll(remote.getOutputSymbols()) .build(),