@Override public String toString() { if (isAll()) { return "TupleDomain{ALL}"; } if (isNone()) { return "TupleDomain{NONE}"; } return "TupleDomain{...}"; }
/** * Returns true only if there exists a strict intersection between the TupleDomains. * i.e. there exists some potential tuple that would be allowable in both TupleDomains. */ public boolean overlaps(TupleDomain<T> other) { return !this.intersect(other).isNone(); }
public TupleDomain<T> simplify() { if (isNone()) { return this; } Map<T, Domain> simplified = domains.get().entrySet().stream() .collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().simplify())); return TupleDomain.withColumnDomains(simplified); }
public String toString(ConnectorSession session) { StringBuilder buffer = new StringBuilder(); if (isAll()) { buffer.append("ALL"); } else if (isNone()) { buffer.append("NONE"); } else { buffer.append(domains.get().entrySet().stream() .collect(toMap(Map.Entry::getKey, entry -> entry.getValue().toString(session)))); } return buffer.toString(); }
public Expression toPredicate(TupleDomain<Symbol> tupleDomain) { if (tupleDomain.isNone()) { return FALSE_LITERAL; } Map<Symbol, Domain> domains = tupleDomain.getDomains().get(); return domains.entrySet().stream() .sorted(comparing(entry -> entry.getKey().getName())) .map(entry -> toPredicate(entry.getValue(), entry.getKey().toSymbolReference())) .collect(collectingAndThen(toImmutableList(), ExpressionUtils::combineConjuncts)); }
private void printConstraint(int indent, ColumnHandle column, TupleDomain<ColumnHandle> constraint) { checkArgument(!constraint.isNone()); Map<ColumnHandle, Domain> domains = constraint.getDomains().get(); if (!constraint.isAll() && domains.containsKey(column)) { print(indent, ":: %s", formatDomain(domains.get(column).simplify())); } }
/** * Returns true only if the this TupleDomain contains all possible tuples that would be allowable by * the other TupleDomain. */ public boolean contains(TupleDomain<T> other) { return other.isNone() || columnWiseUnion(this, other).equals(this); }
/** * Returns the strict intersection of the TupleDomains. * The resulting TupleDomain represents the set of tuples that would be valid * in both TupleDomains. */ public TupleDomain<T> intersect(TupleDomain<T> other) { if (this.isNone() || other.isNone()) { return none(); } Map<T, Domain> intersected = new HashMap<>(this.getDomains().get()); for (Map.Entry<T, Domain> entry : other.getDomains().get().entrySet()) { Domain intersectionDomain = intersected.get(entry.getKey()); if (intersectionDomain == null) { intersected.put(entry.getKey(), entry.getValue()); } else { intersected.put(entry.getKey(), intersectionDomain.intersect(entry.getValue())); } } return withColumnDomains(intersected); }
public static Optional<String> stringFilter(TupleDomain<Integer> constraint, int index) { if (constraint.isNone()) { return Optional.empty(); } Domain domain = constraint.getDomains().get().get(index); if ((domain == null) || !domain.isSingleValue()) { return Optional.empty(); } Object value = domain.getSingleValue(); if (value instanceof Slice) { return Optional.of(((Slice) value).toStringUtf8()); } return Optional.empty(); }
private List<CassandraPartition> getCassandraPartitions(CassandraTable table, TupleDomain<ColumnHandle> tupleDomain) { if (tupleDomain.isNone()) { return ImmutableList.of(); } List<Set<Object>> partitionKeysList = getPartitionKeysList(table, tupleDomain); Set<List<Object>> filterList = Sets.cartesianProduct(partitionKeysList); // empty filters means, all partitions if (filterList.isEmpty()) { return cassandraSession.getPartitions(table, ImmutableList.of()); } return cassandraSession.getPartitions(table, partitionKeysList); }
private Set<ColumnConstraint> parseConstraints(TableHandle tableHandle, TupleDomain<ColumnHandle> constraint) { checkArgument(!constraint.isNone()); ImmutableSet.Builder<ColumnConstraint> columnConstraints = ImmutableSet.builder(); for (Map.Entry<ColumnHandle, Domain> entry : constraint.getDomains().get().entrySet()) { ColumnMetadata columnMetadata = metadata.getColumnMetadata(session, tableHandle, entry.getKey()); columnConstraints.add(new ColumnConstraint( columnMetadata.getName(), columnMetadata.getType().getTypeSignature(), parseDomain(entry.getValue().simplify()))); } return columnConstraints.build(); }
private static boolean isEqualRange(TupleDomain<Symbol> tupleDomain, Symbol symbol, long upperBound) { if (tupleDomain.isNone()) { return false; } Domain domain = tupleDomain.getDomains().get().get(symbol); return domain.getValues().equals(ValueSet.ofRanges(Range.lessThanOrEqual(domain.getType(), upperBound))); }
private <T> Optional<Set<String>> filterString(TupleDomain<T> constraint, T column) { if (constraint.isNone()) { return Optional.of(ImmutableSet.of()); } Domain domain = constraint.getDomains().get().get(column); if (domain == null) { return Optional.empty(); } if (domain.isSingleValue()) { return Optional.of(ImmutableSet.of(((Slice) domain.getSingleValue()).toStringUtf8())); } else if (domain.getValues() instanceof EquatableValueSet) { Collection<Object> values = ((EquatableValueSet) domain.getValues()).getValues(); return Optional.of(values.stream() .map(Slice.class::cast) .map(Slice::toStringUtf8) .collect(toImmutableSet())); } return Optional.empty(); }
public static TupleDomain<ColumnDescriptor> getParquetTupleDomain(Map<List<String>, RichColumnDescriptor> descriptorsByPath, TupleDomain<HiveColumnHandle> effectivePredicate) { if (effectivePredicate.isNone()) { return TupleDomain.none(); } ImmutableMap.Builder<ColumnDescriptor, Domain> predicate = ImmutableMap.builder(); for (Entry<HiveColumnHandle, Domain> entry : effectivePredicate.getDomains().get().entrySet()) { HiveColumnHandle columnHandle = entry.getKey(); // skip looking up predicates for complex types as Parquet only stores stats for primitives if (!columnHandle.getHiveType().getCategory().equals(PRIMITIVE)) { continue; } RichColumnDescriptor descriptor = descriptorsByPath.get(ImmutableList.of(columnHandle.getName())); if (descriptor != null) { predicate.put(descriptor, entry.getValue()); } } return TupleDomain.withColumnDomains(predicate.build()); }
@Test public void testIsNone() { assertFalse(TupleDomain.withColumnDomains(ImmutableMap.<ColumnHandle, Domain>of()).isNone()); assertFalse(TupleDomain.withColumnDomains(ImmutableMap.of(A, Domain.singleValue(BIGINT, 0L))).isNone()); assertTrue(TupleDomain.withColumnDomains(ImmutableMap.of(A, Domain.none(BIGINT))).isNone()); assertFalse(TupleDomain.withColumnDomains(ImmutableMap.of(A, Domain.all(BIGINT))).isNone()); assertTrue(TupleDomain.withColumnDomains(ImmutableMap.of(A, Domain.all(BIGINT), B, Domain.none(BIGINT))).isNone()); }
private void assertPredicateIsAlwaysFalse(Expression expression) { ExtractionResult result = fromPredicate(expression); assertEquals(result.getRemainingExpression(), TRUE_LITERAL); assertTrue(result.getTupleDomain().isNone()); }
private boolean rowMatchesPredicate() { if (predicate.isAll()) { return true; } if (predicate.isNone()) { return false; } Map<ColumnHandle, NullableValue> rowMap = predicate.getDomains().get().keySet().stream() .collect(toImmutableMap( column -> column, column -> { TpchColumnHandle tpchColumnHandle = (TpchColumnHandle) column; Type type = tpchColumnHandle.getType(); TpchColumn tpchColumn = table.getColumn(tpchColumnHandle.getColumnName()); return NullableValue.of(type, getPrestoObject(tpchColumn, type)); })); TupleDomain<ColumnHandle> rowTupleDomain = TupleDomain.fromFixedValues(rowMap); return predicate.contains(rowTupleDomain); }
@Override public List<TableLayoutResult> getLayouts(Session session, TableHandle table, Constraint<ColumnHandle> constraint, Optional<Set<ColumnHandle>> desiredColumns) { if (constraint.getSummary().isNone()) { return ImmutableList.of(); } ConnectorId connectorId = table.getConnectorId(); ConnectorTableHandle connectorTable = table.getConnectorHandle(); CatalogMetadata catalogMetadata = getCatalogMetadata(session, connectorId); ConnectorMetadata metadata = catalogMetadata.getMetadataFor(connectorId); ConnectorTransactionHandle transaction = catalogMetadata.getTransactionHandleFor(connectorId); ConnectorSession connectorSession = session.toConnectorSession(connectorId); List<ConnectorTableLayoutResult> layouts = metadata.getTableLayouts(connectorSession, connectorTable, constraint, desiredColumns); return layouts.stream() .map(layout -> new TableLayoutResult(fromConnectorLayout(connectorId, transaction, layout.getTableLayout()), layout.getUnenforcedConstraint())) .collect(toImmutableList()); }
@Test public void testNone() { assertTrue(TupleDomain.none().isNone()); assertEquals(TupleDomain.<ColumnHandle>none(), TupleDomain.withColumnDomains(ImmutableMap.of( A, Domain.none(BIGINT)))); assertEquals(TupleDomain.<ColumnHandle>none(), TupleDomain.withColumnDomains(ImmutableMap.of( A, Domain.all(BIGINT), B, Domain.none(VARCHAR)))); }
@Override public List<ConnectorTableLayoutResult> getTableLayouts(ConnectorSession session, ConnectorTableHandle table, Constraint<ColumnHandle> constraint, Optional<Set<ColumnHandle>> desiredColumns) { if (constraint.getSummary().isNone()) { return ImmutableList.of(); } InformationSchemaTableHandle handle = checkTableHandle(table); Set<QualifiedTablePrefix> prefixes = calculatePrefixesWithSchemaName(session, constraint.getSummary(), constraint.predicate()); if (isTablesEnumeratingTable(handle.getSchemaTableName())) { Set<QualifiedTablePrefix> tablePrefixes = calculatePrefixesWithTableName(session, prefixes, constraint.getSummary(), constraint.predicate()); // in case of high number of prefixes it is better to populate all data and then filter if (tablePrefixes.size() <= MAX_PREFIXES_COUNT) { prefixes = tablePrefixes; } } if (prefixes.size() > MAX_PREFIXES_COUNT) { // in case of high number of prefixes it is better to populate all data and then filter prefixes = ImmutableSet.of(new QualifiedTablePrefix(catalogName)); } ConnectorTableLayout layout = new ConnectorTableLayout(new InformationSchemaTableLayoutHandle(handle, prefixes)); return ImmutableList.of(new ConnectorTableLayoutResult(layout, constraint.getSummary())); }