[fix](meta) show partitions with Limit for external HMS tables (27835) (#27835)
This enhancement shall extend existing logic for SHOW PARTITIONS FROM to include: - Limit/Offset Where [partition name only] [equal operator and like operator] Order by [partition name only] Issue Number: close #27834
This commit is contained in:
@ -58,7 +58,7 @@ public class ShowPartitionsStmt extends ShowStmt {
|
||||
private static final Logger LOG = LogManager.getLogger(ShowPartitionsStmt.class);
|
||||
|
||||
private static final String FILTER_PARTITION_ID = "PartitionId";
|
||||
private static final String FILTER_PARTITION_NAME = "PartitionName";
|
||||
public static final String FILTER_PARTITION_NAME = "PartitionName";
|
||||
private static final String FILTER_STATE = "State";
|
||||
private static final String FILTER_BUCKETS = "Buckets";
|
||||
private static final String FILTER_REPLICATION_NUM = "ReplicationNum";
|
||||
@ -198,6 +198,11 @@ public class ShowPartitionsStmt extends ShowStmt {
|
||||
throw new AnalysisException("Should order by column");
|
||||
}
|
||||
SlotRef slotRef = (SlotRef) orderByElement.getExpr();
|
||||
if (catalog instanceof HMSExternalCatalog
|
||||
&& !slotRef.getColumnName().equalsIgnoreCase(FILTER_PARTITION_NAME)) {
|
||||
throw new AnalysisException("External table only support Order By on PartitionName");
|
||||
}
|
||||
|
||||
int index = PartitionsProcDir.analyzeColumn(slotRef.getColumnName());
|
||||
OrderByPair orderByPair = new OrderByPair(index, !orderByElement.getIsAsc());
|
||||
orderByPairs.add(orderByPair);
|
||||
@ -228,6 +233,10 @@ public class ShowPartitionsStmt extends ShowStmt {
|
||||
}
|
||||
|
||||
String leftKey = ((SlotRef) subExpr.getChild(0)).getColumnName();
|
||||
if (catalog instanceof HMSExternalCatalog && !leftKey.equalsIgnoreCase(FILTER_PARTITION_NAME)) {
|
||||
throw new AnalysisException(String.format("Only %s column supported in where clause for this catalog",
|
||||
FILTER_PARTITION_NAME));
|
||||
}
|
||||
if (subExpr instanceof BinaryPredicate) {
|
||||
BinaryPredicate binaryPredicate = (BinaryPredicate) subExpr;
|
||||
if (leftKey.equalsIgnoreCase(FILTER_PARTITION_NAME) || leftKey.equalsIgnoreCase(FILTER_STATE)) {
|
||||
|
||||
@ -81,7 +81,8 @@ public class PartitionsProcDir implements ProcDirInterface {
|
||||
this.isTempPartition = isTempPartition;
|
||||
}
|
||||
|
||||
public boolean filter(String columnName, Comparable element, Map<String, Expr> filterMap) throws AnalysisException {
|
||||
public static boolean filter(String columnName, Comparable element, Map<String, Expr> filterMap)
|
||||
throws AnalysisException {
|
||||
if (filterMap == null) {
|
||||
return true;
|
||||
}
|
||||
@ -142,7 +143,7 @@ public class PartitionsProcDir implements ProcDirInterface {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean like(String str, String expr) {
|
||||
public static boolean like(String str, String expr) {
|
||||
expr = expr.toLowerCase();
|
||||
expr = expr.replace(".", "\\.");
|
||||
expr = expr.replace("?", ".");
|
||||
|
||||
@ -24,6 +24,7 @@ import org.apache.doris.analysis.AdminShowReplicaDistributionStmt;
|
||||
import org.apache.doris.analysis.AdminShowReplicaStatusStmt;
|
||||
import org.apache.doris.analysis.AdminShowTabletStorageFormatStmt;
|
||||
import org.apache.doris.analysis.DescribeStmt;
|
||||
import org.apache.doris.analysis.Expr;
|
||||
import org.apache.doris.analysis.HelpStmt;
|
||||
import org.apache.doris.analysis.LimitElement;
|
||||
import org.apache.doris.analysis.PartitionNames;
|
||||
@ -1655,28 +1656,53 @@ public class ShowExecutor {
|
||||
resultSet = new ShowResultSet(showStmt.getMetaData(), rows);
|
||||
}
|
||||
|
||||
private void handleShowHMSTablePartitions(ShowPartitionsStmt showStmt) {
|
||||
private void handleShowHMSTablePartitions(ShowPartitionsStmt showStmt) throws AnalysisException {
|
||||
HMSExternalCatalog catalog = (HMSExternalCatalog) (showStmt.getCatalog());
|
||||
List<List<String>> rows = new ArrayList<>();
|
||||
String dbName = ClusterNamespace.getNameFromFullName(showStmt.getTableName().getDb());
|
||||
|
||||
List<String> partitionNames;
|
||||
LimitElement limit = showStmt.getLimitElement();
|
||||
if (limit != null && limit.hasLimit()) {
|
||||
// only limit is valid on Hive
|
||||
Map<String, Expr> filterMap = showStmt.getFilterMap();
|
||||
List<OrderByPair> orderByPairs = showStmt.getOrderByPairs();
|
||||
|
||||
if (limit != null && limit.hasLimit() && limit.getOffset() == 0
|
||||
&& (orderByPairs == null || !orderByPairs.get(0).isDesc())) {
|
||||
// hmsClient returns unordered partition list, hence if offset > 0 cannot pass limit
|
||||
partitionNames = catalog.getClient()
|
||||
.listPartitionNames(dbName, showStmt.getTableName().getTbl(), limit.getLimit());
|
||||
.listPartitionNames(dbName, showStmt.getTableName().getTbl(), limit.getLimit());
|
||||
} else {
|
||||
partitionNames = catalog.getClient().listPartitionNames(dbName, showStmt.getTableName().getTbl());
|
||||
}
|
||||
|
||||
/* Filter add rows */
|
||||
for (String partition : partitionNames) {
|
||||
List<String> list = new ArrayList<>();
|
||||
|
||||
if (filterMap != null && !filterMap.isEmpty()) {
|
||||
if (!PartitionsProcDir.filter(ShowPartitionsStmt.FILTER_PARTITION_NAME, partition, filterMap)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
list.add(partition);
|
||||
rows.add(list);
|
||||
}
|
||||
|
||||
// sort by partition name
|
||||
rows.sort(Comparator.comparing(x -> x.get(0)));
|
||||
if (orderByPairs != null && orderByPairs.get(0).isDesc()) {
|
||||
rows.sort(Comparator.comparing(x -> x.get(0), Comparator.reverseOrder()));
|
||||
} else {
|
||||
rows.sort(Comparator.comparing(x -> x.get(0)));
|
||||
}
|
||||
|
||||
if (limit != null && limit.hasLimit()) {
|
||||
int beginIndex = (int) limit.getOffset();
|
||||
int endIndex = (int) (beginIndex + limit.getLimit());
|
||||
if (endIndex > rows.size()) {
|
||||
endIndex = rows.size();
|
||||
}
|
||||
rows = rows.subList(beginIndex, endIndex);
|
||||
}
|
||||
|
||||
resultSet = new ShowResultSet(showStmt.getMetaData(), rows);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user