Пример #1
0
    private PlanNode planTableScan(TableScanNode node, Expression predicate, Context context) {
      DomainTranslator.ExtractionResult decomposedPredicate =
          DomainTranslator.fromPredicate(metadata, session, predicate, symbolAllocator.getTypes());

      TupleDomain<ColumnHandle> simplifiedConstraint =
          decomposedPredicate
              .getTupleDomain()
              .transform(node.getAssignments()::get)
              .intersect(node.getCurrentConstraint());

      checkState(node.getOutputSymbols().containsAll(context.getLookupSymbols()));

      Set<ColumnHandle> lookupColumns =
          context
              .getLookupSymbols()
              .stream()
              .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()) {
        // No index available, so give up by returning something
        return node;
      }
      ResolvedIndex resolvedIndex = optionalResolvedIndex.get();

      Map<ColumnHandle, Symbol> inverseAssignments =
          ImmutableBiMap.copyOf(node.getAssignments()).inverse();

      PlanNode source =
          new IndexSourceNode(
              idAllocator.getNextId(),
              resolvedIndex.getIndexHandle(),
              node.getTable(),
              node.getLayout(),
              context.getLookupSymbols(),
              node.getOutputSymbols(),
              node.getAssignments(),
              simplifiedConstraint);

      Expression resultingPredicate =
          combineConjuncts(
              DomainTranslator.toPredicate(
                  resolvedIndex.getUnresolvedTupleDomain().transform(inverseAssignments::get)),
              decomposedPredicate.getRemainingExpression());

      if (!resultingPredicate.equals(TRUE_LITERAL)) {
        // todo it is likely we end up with redundant filters here because the predicate push down
        // has already been run... the fix is to run predicate push down again
        source = new FilterNode(idAllocator.getNextId(), source, resultingPredicate);
      }
      context.markSuccess();
      return source;
    }