ExternalTablePreloadInfo.java
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package org.apache.doris.nereids;
import org.apache.doris.catalog.PartitionItem;
import org.apache.doris.datasource.ExternalTable;
import java.util.Map;
import java.util.Optional;
/** Tracks how a single external table is referenced before metadata preload happens. */
public class ExternalTablePreloadInfo {
private final ExternalTable table;
private boolean hasLatestOnlyRelation;
private boolean hasNonLatestRelation;
private boolean hasUnfilteredLatestRelation;
/**
* The scan-path partition view materialized by the pre-lock preload pass, or {@code null} when that pass
* did not run (or did not warm one). An {@link Optional#empty()} value is meaningful and different from
* {@code null}: the connector view is UNAVAILABLE (unrepresentable partition), which every scan-path
* consumer must read as "scan every partition".
*/
private Optional<Map<String, PartitionItem>> scanPartitionView;
/**
* The complete latest partition view needed by async-MV partition mapping, or {@code null} when that view was
* not requested for this statement. It is intentionally independent from {@link #scanPartitionView}: a
* filtered scan must keep connector predicate pruning instead of being forced through this full view.
* {@link Optional#empty()} means the complete view is UNAVAILABLE, while an optional containing an empty map
* is the authoritative view of a table with no partitions.
*/
private Optional<Map<String, PartitionItem>> mtmvPartitionView;
public ExternalTablePreloadInfo(ExternalTable table) {
this.table = table;
}
public ExternalTable getTable() {
return table;
}
public void markLatestRelation() {
hasLatestOnlyRelation = true;
}
public void markNonLatestRelation() {
hasNonLatestRelation = true;
}
public void markUnfilteredLatestRelation() {
hasUnfilteredLatestRelation = true;
}
public boolean hasLatestOnlyRelation() {
return hasLatestOnlyRelation;
}
public boolean hasNonLatestRelation() {
return hasNonLatestRelation;
}
public boolean shouldPreloadLatestSnapshot() {
// A historical alias has independent scan state and must not cancel the latest alias warmup.
return hasLatestOnlyRelation;
}
/**
* Whether at least one latest relation had no initial LogicalFilter. The pre-lock full-view warmup is
* only useful for such a scan; a selectively filtered relation must let connector pruning avoid it.
*/
public boolean shouldPreloadUnfilteredScanPartitionView() {
return hasUnfilteredLatestRelation;
}
/** Whether the pre-lock preload pass materialized this table's scan partition view. */
public boolean hasScanPartitionView() {
return scanPartitionView != null;
}
/**
* The scan-path partition view materialized before the internal table locks were taken, so a lock-sensitive
* consumer reuses it instead of paying connector I/O under the lock. Only valid when
* {@link #hasScanPartitionView()} is true.
*/
public Optional<Map<String, PartitionItem>> getScanPartitionView() {
return scanPartitionView;
}
public void setScanPartitionView(Optional<Map<String, PartitionItem>> scanPartitionView) {
this.scanPartitionView = scanPartitionView;
}
/** Whether the pre-lock pass materialized the complete view required by async-MV partition mapping. */
public boolean hasMtmvPartitionView() {
return mtmvPartitionView != null;
}
/**
* The complete partition view materialized before internal table locks were taken. Only valid when
* {@link #hasMtmvPartitionView()} is true.
*/
public Optional<Map<String, PartitionItem>> getMtmvPartitionView() {
return mtmvPartitionView;
}
public void setMtmvPartitionView(Optional<Map<String, PartitionItem>> mtmvPartitionView) {
this.mtmvPartitionView = mtmvPartitionView;
}
/** Drops per-execution views so a later execution of a reused statement does not read a stale generation. */
public void clearPartitionViews() {
this.scanPartitionView = null;
this.mtmvPartitionView = null;
}
}