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 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 ActualProperties visitTableScan(TableScanNode node, List<ActualProperties> 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(); ActualProperties.Builder properties = ActualProperties.builder(); // Globally constant assignments Map<ColumnHandle, NullableValue> globalConstants = new HashMap<>(); extractFixedValues(node.getCurrentConstraint()).orElse(ImmutableMap.of()) .entrySet().stream() .filter(entry -> !entry.getValue().isNull()) .forEach(entry -> globalConstants.put(entry.getKey(), entry.getValue())); Map<Symbol, NullableValue> symbolConstants = globalConstants.entrySet().stream() .filter(entry -> assignments.containsKey(entry.getKey())) .collect(toMap(entry -> assignments.get(entry.getKey()), Map.Entry::getValue)); properties.constants(symbolConstants); // Partitioning properties properties.global(deriveGlobalProperties(layout, assignments, globalConstants)); // Append the global constants onto the local properties to maximize their translation potential List<LocalProperty<ColumnHandle>> constantAppendedLocalProperties = ImmutableList.<LocalProperty<ColumnHandle>>builder() .addAll(globalConstants.keySet().stream().map(ConstantProperty::new).iterator()) .addAll(layout.getLocalProperties()) .build(); properties.local(LocalProperties.translate(constantAppendedLocalProperties, column -> Optional.ofNullable(assignments.get(column)))); return properties.build(); }
@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); }
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 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, stageExecutionDescriptor.isScanGroupedExecution(node.getId()) ? GROUPED_EXECUTION : UNGROUPED_EXECUTION); }
@Override public PlanNode visitTableScan(TableScanNode node, RewriteContext<Set<Symbol>> context) { List<Symbol> newOutputs = node.getOutputSymbols().stream() .filter(context.get()::contains) .collect(toImmutableList()); Map<Symbol, ColumnHandle> newAssignments = newOutputs.stream() .collect(Collectors.toMap(Function.identity(), node.getAssignments()::get)); return new TableScanNode( node.getId(), node.getTable(), newOutputs, newAssignments, node.getLayout(), node.getCurrentConstraint(), node.getEnforcedConstraint()); }
@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 PlanNode visitTableScan(TableScanNode node, RewriteContext<Void> context) { PartitioningHandle partitioning = node.getLayout() .map(layout -> metadata.getLayout(session, layout)) .flatMap(TableLayout::getTablePartitioning) .map(TablePartitioning::getPartitioningHandle) .orElse(SOURCE_DISTRIBUTION); if (partitioning.equals(fragmentPartitioningHandle)) { // do nothing if the current scan node's partitioning matches the fragment's return node; } TableLayoutHandle newTableLayoutHandle = metadata.getAlternativeLayoutHandle(session, node.getLayout().get(), fragmentPartitioningHandle); return new TableScanNode( node.getId(), node.getTable(), node.getOutputSymbols(), node.getAssignments(), Optional.of(newTableLayoutHandle), node.getCurrentConstraint(), node.getEnforcedConstraint()); } }
@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 Expression visitTableScan(TableScanNode node, Void context) { Map<ColumnHandle, Symbol> assignments = ImmutableBiMap.copyOf(node.getAssignments()).inverse(); return domainTranslator.toPredicate(node.getCurrentConstraint().simplify().transform(assignments::get)); }
.transform(node.getAssignments()::get) .intersect(node.getEnforcedConstraint()); .map(node.getAssignments()::get) .collect(toImmutableSet()); Set<ColumnHandle> outputColumns = node.getOutputSymbols().stream().map(node.getAssignments()::get).collect(toImmutableSet()); Map<ColumnHandle, Symbol> inverseAssignments = ImmutableBiMap.copyOf(node.getAssignments()).inverse(); context.getLookupSymbols(), node.getOutputSymbols(), node.getAssignments(), simplifiedConstraint);
ColumnHandle column = tableScan.getAssignments().get(symbol); ColumnMetadata columnMetadata = metadata.getColumnMetadata(session, tableScan.getTable(), column);
int channel = 0; for (Symbol symbol : tableScanNode.getOutputSymbols()) { columns.add(tableScanNode.getAssignments().get(symbol));
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); handle, scan.getOutputSymbols(), scan.getAssignments(), Optional.of(layoutResult.getLayout().getHandle()), layoutResult.getLayout().getPredicate(),
.transform(node.getAssignments()::get) .intersect(node.getEnforcedConstraint()); Map<ColumnHandle, Symbol> assignments = ImmutableBiMap.copyOf(node.getAssignments()).inverse(); session, types, node.getAssignments(), combineConjuncts( deterministicPredicate, constraint, Optional.of(node.getOutputSymbols().stream() .map(node.getAssignments()::get) .collect(toImmutableSet()))); node.getTable(), node.getOutputSymbols(), node.getAssignments(), Optional.of(layout.getLayout().getHandle()), layout.getLayout().getPredicate(),
@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 Void visitTableScan(TableScanNode node, Void context) { builder.addAll(node.getAssignments().keySet()); return null; }
@Override public Void visitTableScan(TableScanNode node, Void context) { verifyUniqueId(node); checkArgument(node.getAssignments().keySet().containsAll(node.getOutputSymbols()), "Assignments must contain mappings for output symbols"); return null; }
private Predicate<TableLayoutResult> layoutHasAllNeededOutputs(TableScanNode node) { return layout -> !layout.getLayout().getColumns().isPresent() || layout.getLayout().getColumns().get().containsAll(Lists.transform(node.getOutputSymbols(), node.getAssignments()::get)); }