[enhancement](Nereids)print slot name in explain string (#12272)

Currently, explain string print all expression as slot id, e.g. `<slot 1>`.
This PR, print its name with slot id instead, e.g. `column_a[#1]`. For details:
- print qualified table name for OlapScanNode
- print NamedExpression name with SlotId instead of just SlotId
- OlapScanNode's node name use "OlapScanNode" instead of table name
This commit is contained in:
morrySnow
2022-09-05 11:31:35 +08:00
committed by GitHub
parent e5f3f0e730
commit 2398cd3bb6
23 changed files with 97 additions and 67 deletions

View File

@ -26,6 +26,7 @@ import org.apache.doris.catalog.Type;
import org.apache.doris.common.AnalysisException;
import org.apache.doris.common.io.Text;
import org.apache.doris.common.util.ToSqlContext;
import org.apache.doris.qe.ConnectContext;
import org.apache.doris.thrift.TExprNode;
import org.apache.doris.thrift.TExprNodeType;
import org.apache.doris.thrift.TSlotRef;
@ -205,9 +206,15 @@ public class SlotRef extends Expr {
StringBuilder sb = new StringBuilder();
if (tblName != null) {
return tblName.toSql() + "." + label + sb.toString();
return tblName.toSql() + "." + label;
} else if (label != null) {
return label + sb.toString();
if (ConnectContext.get() != null
&& ConnectContext.get().getSessionVariable() != null
&& ConnectContext.get().getSessionVariable().isEnableNereidsPlanner()) {
return label + "[#" + desc.getId().asInt() + "]";
} else {
return label;
}
} else if (desc.getSourceExprs() != null) {
if (ToSqlContext.get() == null || ToSqlContext.get().isNeedSlotRefId()) {
if (desc.getId().asInt() != 1) {

View File

@ -193,6 +193,9 @@ public class Database extends MetaObject implements Writable, DatabaseIf<Table>
writeLock();
try {
this.fullQualifiedName = newName;
for (Table table : idToTable.values()) {
table.setQualifiedDbName(fullQualifiedName);
}
} finally {
writeUnlock();
}
@ -361,6 +364,7 @@ public class Database extends MetaObject implements Writable, DatabaseIf<Table>
public boolean createTable(Table table) {
boolean result = true;
table.setQualifiedDbName(fullQualifiedName);
String tableName = table.getName();
if (Env.isStoredTableNamesLowerCase()) {
tableName = tableName.toLowerCase();
@ -564,6 +568,7 @@ public class Database extends MetaObject implements Writable, DatabaseIf<Table>
int numTables = in.readInt();
for (int i = 0; i < numTables; ++i) {
Table table = Table.read(in);
table.setQualifiedDbName(fullQualifiedName);
String tableName = table.getName();
nameToTable.put(tableName, table);
idToTable.put(table.getId(), table);
@ -651,6 +656,9 @@ public class Database extends MetaObject implements Writable, DatabaseIf<Table>
public void setName(String name) {
this.fullQualifiedName = name;
for (Table table : nameToTable.values()) {
table.setQualifiedDbName(name);
}
}
public synchronized void addFunction(Function function) throws UserException {

View File

@ -71,6 +71,7 @@ public class PartitionInfo implements Writable {
protected Map<Long, TTabletType> idToTabletType;
public PartitionInfo() {
this.type = PartitionType.UNPARTITIONED;
this.idToDataProperty = new HashMap<>();
this.idToReplicaAllocation = new HashMap<>();
this.idToInMemory = new HashMap<>();

View File

@ -33,6 +33,7 @@ import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.commons.lang.NotImplementedException;
import org.apache.commons.lang.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@ -60,6 +61,7 @@ public abstract class Table extends MetaObject implements Writable, TableIf {
protected long id;
protected volatile String name;
protected volatile String qualifiedDbName;
protected TableType type;
protected long createTime;
protected ReentrantReadWriteLock rwLock;
@ -248,6 +250,18 @@ public abstract class Table extends MetaObject implements Writable, TableIf {
name = newName;
}
void setQualifiedDbName(String qualifiedDbName) {
this.qualifiedDbName = qualifiedDbName;
}
public String getQualifiedName() {
if (StringUtils.isEmpty(qualifiedDbName)) {
return name;
} else {
return qualifiedDbName + "." + name;
}
}
public TableType getType() {
return type;
}

View File

@ -217,13 +217,13 @@ public class PhysicalPlanTranslator extends DefaultPlanVisitor<PlanFragment, Pla
OlapTable olapTable = olapScan.getTable();
TupleDescriptor tupleDescriptor = generateTupleDesc(slotList, olapTable, context);
tupleDescriptor.setTable(olapTable);
OlapScanNode olapScanNode = new OlapScanNode(context.nextPlanNodeId(), tupleDescriptor, olapTable.getName());
OlapScanNode olapScanNode = new OlapScanNode(context.nextPlanNodeId(), tupleDescriptor, "OlapScanNode");
// TODO: Do we really need tableName here?
TableName tableName = new TableName(null, "", "");
TableRef ref = new TableRef(tableName, null, null);
BaseTableRef tableRef = new BaseTableRef(ref, olapTable, tableName);
tupleDescriptor.setRef(tableRef);
olapScanNode.setSelectedPartitionIds(olapScan.getSelectedPartitionId());
olapScanNode.setSelectedPartitionIds(olapScan.getSelectedPartitionIds());
try {
olapScanNode.updateScanRangeInfoByNewMVSelector(olapScan.getSelectedIndexId(), false, "");
} catch (Exception e) {

View File

@ -121,7 +121,9 @@ public class PlanTranslatorContext {
}
slotDescriptor.setType(slotReference.getDataType().toCatalogDataType());
slotDescriptor.setIsMaterialized(true);
this.addExprIdSlotRefPair(slotReference.getExprId(), new SlotRef(slotDescriptor));
SlotRef slotRef = new SlotRef(slotDescriptor);
slotRef.setLabel(slotReference.getName());
this.addExprIdSlotRefPair(slotReference.getExprId(), slotRef);
slotDescriptor.setIsNullable(slotReference.nullable());
return slotDescriptor;
}

View File

@ -85,7 +85,7 @@ public class LogicalOlapScan extends LogicalRelation {
@Override
public String toString() {
return Utils.toSqlString("LogicalOlapScan",
"qualifier", qualifiedName(),
"qualified", qualifiedName(),
"output", getOutput()
);
}

View File

@ -29,7 +29,6 @@ import org.apache.doris.nereids.trees.plans.visitor.PlanVisitor;
import org.apache.doris.nereids.util.Utils;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import java.util.Collections;
import java.util.List;
@ -43,8 +42,7 @@ public abstract class LogicalRelation extends LogicalLeaf implements Scan {
protected final Table table;
protected final List<String> qualifier;
protected List<Long> selectedPartitionIds = Lists.newArrayList();
protected final List<Long> selectedPartitionIds;
public LogicalRelation(PlanType type, Table table, List<String> qualifier) {
this(type, table, qualifier, Optional.empty(), Optional.empty(), Collections.emptyList());
@ -57,13 +55,13 @@ public abstract class LogicalRelation extends LogicalLeaf implements Scan {
* @param qualifier qualified relation name
*/
public LogicalRelation(PlanType type, Table table, List<String> qualifier,
Optional<GroupExpression> groupExpression,
Optional<LogicalProperties> logicalProperties,
List<Long> selectedPartitionIdList) {
Optional<GroupExpression> groupExpression, Optional<LogicalProperties> logicalProperties,
List<Long> selectedPartitionIds) {
super(type, groupExpression, logicalProperties);
this.table = Objects.requireNonNull(table, "table can not be null");
this.qualifier = ImmutableList.copyOf(Objects.requireNonNull(qualifier, "qualifier can not be null"));
this.selectedPartitionIds = selectedPartitionIdList;
this.selectedPartitionIds = ImmutableList.copyOf(
Objects.requireNonNull(selectedPartitionIds, "selectedPartitionIds can not be null"));
}
public Table getTable() {

View File

@ -37,8 +37,8 @@ public class PhysicalOlapScan extends PhysicalRelation {
private final OlapTable olapTable;
private final DistributionSpec distributionSpec;
private final long selectedIndexId;
private final List<Long> selectedTabletId;
private final List<Long> selectedPartitionId;
private final List<Long> selectedTabletIds;
private final List<Long> selectedPartitionIds;
/**
* Constructor for PhysicalOlapScan.
@ -47,14 +47,13 @@ public class PhysicalOlapScan extends PhysicalRelation {
* @param qualifier qualifier of table name
*/
public PhysicalOlapScan(OlapTable olapTable, List<String> qualifier, long selectedIndexId,
List<Long> selectedTabletId, List<Long> selectedPartitionId, DistributionSpec distributionSpec,
List<Long> selectedTabletIds, List<Long> selectedPartitionIds, DistributionSpec distributionSpec,
Optional<GroupExpression> groupExpression, LogicalProperties logicalProperties) {
super(PlanType.PHYSICAL_OLAP_SCAN, qualifier, groupExpression, logicalProperties);
this.olapTable = olapTable;
this.selectedIndexId = selectedIndexId;
this.selectedTabletId = selectedTabletId;
this.selectedPartitionId = selectedPartitionId;
this.selectedTabletIds = selectedTabletIds;
this.selectedPartitionIds = selectedPartitionIds;
this.distributionSpec = distributionSpec;
}
@ -62,12 +61,12 @@ public class PhysicalOlapScan extends PhysicalRelation {
return selectedIndexId;
}
public List<Long> getSelectedTabletId() {
return selectedTabletId;
public List<Long> getSelectedTabletIds() {
return selectedTabletIds;
}
public List<Long> getSelectedPartitionId() {
return selectedPartitionId;
public List<Long> getSelectedPartitionIds() {
return selectedPartitionIds;
}
public OlapTable getTable() {
@ -81,7 +80,7 @@ public class PhysicalOlapScan extends PhysicalRelation {
@Override
public String toString() {
return Utils.toSqlString("PhysicalOlapScan",
"qualifier", Utils.qualifiedName(qualifier, olapTable.getName()),
"qualified", Utils.qualifiedName(qualifier, olapTable.getName()),
"output", getOutput()
);
}
@ -96,14 +95,14 @@ public class PhysicalOlapScan extends PhysicalRelation {
}
PhysicalOlapScan that = (PhysicalOlapScan) o;
return selectedIndexId == that.selectedIndexId
&& Objects.equals(selectedTabletId, that.selectedTabletId)
&& Objects.equals(selectedPartitionId, that.selectedPartitionId)
&& Objects.equals(selectedTabletIds, that.selectedTabletIds)
&& Objects.equals(selectedPartitionIds, that.selectedPartitionIds)
&& Objects.equals(olapTable, that.olapTable);
}
@Override
public int hashCode() {
return Objects.hash(selectedIndexId, selectedPartitionId, selectedTabletId, olapTable);
return Objects.hash(selectedIndexId, selectedPartitionIds, selectedTabletIds, olapTable);
}
@Override
@ -113,13 +112,13 @@ public class PhysicalOlapScan extends PhysicalRelation {
@Override
public Plan withGroupExpression(Optional<GroupExpression> groupExpression) {
return new PhysicalOlapScan(olapTable, qualifier, selectedIndexId, selectedTabletId, selectedPartitionId,
distributionSpec, groupExpression, logicalProperties);
return new PhysicalOlapScan(olapTable, qualifier, selectedIndexId, selectedTabletIds,
selectedPartitionIds, distributionSpec, groupExpression, logicalProperties);
}
@Override
public Plan withLogicalProperties(Optional<LogicalProperties> logicalProperties) {
return new PhysicalOlapScan(olapTable, qualifier, selectedIndexId, selectedTabletId, selectedPartitionId,
distributionSpec, Optional.empty(), logicalProperties.get());
return new PhysicalOlapScan(olapTable, qualifier, selectedIndexId, selectedTabletIds,
selectedPartitionIds, distributionSpec, Optional.empty(), logicalProperties.get());
}
}

View File

@ -43,8 +43,8 @@ public abstract class PhysicalRelation extends PhysicalLeaf implements Scan {
* @param type node type
* @param qualifier table's name
*/
public PhysicalRelation(PlanType type, List<String> qualifier, Optional<GroupExpression> groupExpression,
LogicalProperties logicalProperties) {
public PhysicalRelation(PlanType type, List<String> qualifier,
Optional<GroupExpression> groupExpression, LogicalProperties logicalProperties) {
super(type, groupExpression, logicalProperties);
this.qualifier = Objects.requireNonNull(qualifier, "qualifier can not be null");
}

View File

@ -816,7 +816,8 @@ public class OlapScanNode extends ScanNode {
StringBuilder output = new StringBuilder();
String indexName = olapTable.getIndexNameById(selectedIndexId);
output.append(prefix).append("TABLE: ").append(olapTable.getName()).append("(").append(indexName).append(")");
output.append(prefix).append("TABLE: ").append(olapTable.getQualifiedName())
.append("(").append(indexName).append(")");
if (detailLevel == TExplainLevel.BRIEF) {
return output.toString();
}

View File

@ -48,9 +48,8 @@ public class PhysicalPlanTranslatorTest {
@Test
public void testOlapPrune(@Mocked OlapTable t1, @Injectable LogicalProperties placeHolder) throws Exception {
List<String> qualifierList = new ArrayList<>();
qualifierList.add("test");
qualifierList.add("t1");
List<String> qualifier = new ArrayList<>();
qualifier.add("test");
List<Slot> t1Output = new ArrayList<>();
SlotReference col1 = new SlotReference("col1", IntegerType.INSTANCE);
SlotReference col2 = new SlotReference("col2", IntegerType.INSTANCE);
@ -59,17 +58,17 @@ public class PhysicalPlanTranslatorTest {
t1Output.add(col2);
t1Output.add(col3);
LogicalProperties t1Properties = new LogicalProperties(() -> t1Output);
PhysicalOlapScan scan = new PhysicalOlapScan(t1, qualifierList, 0L,
PhysicalOlapScan scan = new PhysicalOlapScan(t1, qualifier, 0L,
Collections.emptyList(), Collections.emptyList(), null,
Optional.empty(),
t1Properties);
Literal t1FilterRight = new IntegerLiteral(1);
Expression t1FilterExpr = new GreaterThan(col1, t1FilterRight);
PhysicalFilter<PhysicalOlapScan> filter =
new PhysicalFilter(t1FilterExpr, placeHolder, scan);
new PhysicalFilter<>(t1FilterExpr, placeHolder, scan);
List<NamedExpression> projList = new ArrayList<>();
projList.add(col2);
PhysicalProject<PhysicalFilter> project = new PhysicalProject(projList,
PhysicalProject<PhysicalFilter<PhysicalOlapScan>> project = new PhysicalProject<>(projList,
placeHolder, filter);
PlanTranslatorContext planTranslatorContext = new PlanTranslatorContext();
PhysicalPlanTranslator translator = new PhysicalPlanTranslator();

View File

@ -109,8 +109,8 @@ public class RewriteTopDownJobTest {
public LogicalBoundRelation(Table table, List<String> qualifier, Optional<GroupExpression> groupExpression,
Optional<LogicalProperties> logicalProperties) {
super(PlanType.LOGICAL_BOUND_RELATION, table, qualifier, groupExpression, logicalProperties,
Collections.emptyList());
super(PlanType.LOGICAL_BOUND_RELATION, table, qualifier,
groupExpression, logicalProperties, Collections.emptyList());
}
@Override

View File

@ -49,7 +49,7 @@ public class AggregateDisassembleTest {
@BeforeAll
public final void beforeAll() {
rStudent = new LogicalOlapScan(PlanConstructor.student, ImmutableList.of("student"));
rStudent = new LogicalOlapScan(PlanConstructor.student, ImmutableList.of(""));
}
/**

View File

@ -57,8 +57,8 @@ import java.util.Optional;
class FindHashConditionForJoinTest {
@Test
public void testFindHashCondition() {
Plan student = new LogicalOlapScan(PlanConstructor.student, ImmutableList.of("student"));
Plan score = new LogicalOlapScan(PlanConstructor.score, ImmutableList.of("score"));
Plan student = new LogicalOlapScan(PlanConstructor.student, ImmutableList.of(""));
Plan score = new LogicalOlapScan(PlanConstructor.score, ImmutableList.of(""));
Slot studentId = student.getOutput().get(0);
Slot gender = student.getOutput().get(1);

View File

@ -48,7 +48,7 @@ public class NormalizeAggregateTest implements PatternMatchSupported {
@BeforeAll
public final void beforeAll() {
rStudent = new LogicalOlapScan(PlanConstructor.student, ImmutableList.of("student"));
rStudent = new LogicalOlapScan(PlanConstructor.student, ImmutableList.of(""));
}
/**

View File

@ -69,11 +69,11 @@ public class PushDownPredicateTest {
*/
@BeforeAll
public final void beforeAll() {
rStudent = new LogicalOlapScan(PlanConstructor.student, ImmutableList.of("student"));
rStudent = new LogicalOlapScan(PlanConstructor.student, ImmutableList.of(""));
rScore = new LogicalOlapScan(PlanConstructor.score, ImmutableList.of("score"));
rScore = new LogicalOlapScan(PlanConstructor.score, ImmutableList.of(""));
rCourse = new LogicalOlapScan(PlanConstructor.course, ImmutableList.of("course"));
rCourse = new LogicalOlapScan(PlanConstructor.course, ImmutableList.of(""));
}
@Test

View File

@ -70,7 +70,7 @@ public class PushDownPredicateThroughAggregationTest {
*/
@Test
public void pushDownPredicateOneFilterTest() {
Plan scan = new LogicalOlapScan(PlanConstructor.student, ImmutableList.of("student"));
Plan scan = new LogicalOlapScan(PlanConstructor.student, ImmutableList.of(""));
Slot gender = scan.getOutput().get(1);
Slot age = scan.getOutput().get(3);
@ -130,7 +130,7 @@ public class PushDownPredicateThroughAggregationTest {
*/
@Test
public void pushDownPredicateTwoFilterTest() {
Plan scan = new LogicalOlapScan(PlanConstructor.student, ImmutableList.of("student"));
Plan scan = new LogicalOlapScan(PlanConstructor.student, ImmutableList.of(""));
Slot gender = scan.getOutput().get(1);
Slot name = scan.getOutput().get(2);
Slot age = scan.getOutput().get(3);

View File

@ -225,8 +225,8 @@ public class StatsCalculatorTest {
}};
OlapTable table1 = PlanConstructor.newOlapTable(tableId1, "t1", 0);
LogicalOlapScan logicalOlapScan1 = new LogicalOlapScan(table1, Collections.emptyList()).withLogicalProperties(
Optional.of(new LogicalProperties(() -> ImmutableList.of(slot1))));
LogicalOlapScan logicalOlapScan1 = new LogicalOlapScan(table1, Collections.emptyList())
.withLogicalProperties(Optional.of(new LogicalProperties(() -> ImmutableList.of(slot1))));
Group childGroup = new Group();
GroupExpression groupExpression = new GroupExpression(logicalOlapScan1, ImmutableList.of(childGroup));
Group ownerGroup = new Group();

View File

@ -227,9 +227,9 @@ public class PlanEqualsTest {
selectedTabletId.addAll(partition.getBaseIndex().getTabletIdsInOrder());
}
PhysicalOlapScan actual = new PhysicalOlapScan(olapTable, Lists.newArrayList("a"), olapTable.getBaseIndexId(),
selectedTabletId, olapTable.getPartitionIds(), distributionSpecHash, Optional.empty(),
logicalProperties);
PhysicalOlapScan actual = new PhysicalOlapScan(olapTable, Lists.newArrayList("a"),
olapTable.getBaseIndexId(), selectedTabletId, olapTable.getPartitionIds(), distributionSpecHash,
Optional.empty(), logicalProperties);
PhysicalOlapScan expected = new PhysicalOlapScan(olapTable, Lists.newArrayList("a"),
olapTable.getBaseIndexId(), selectedTabletId, olapTable.getPartitionIds(), distributionSpecHash,

View File

@ -82,7 +82,7 @@ public class PlanOutputTest {
@Test
public void testPhysicalPlanMustHaveLogicalProperties() {
Assertions.assertThrows(NullPointerException.class, () ->
new PhysicalRelation(PlanType.PHYSICAL_OLAP_SCAN, ImmutableList.of("tbl"), Optional.empty(), null) {
new PhysicalRelation(PlanType.PHYSICAL_OLAP_SCAN, ImmutableList.of("db"), Optional.empty(), null) {
@Override
public Plan withGroupExpression(Optional<GroupExpression> groupExpression) {
return null;

View File

@ -82,7 +82,7 @@ public class PlanToStringTest {
public void testLogicalOlapScan() {
LogicalOlapScan plan = PlanConstructor.newLogicalOlapScan(0, "table", 0);
Assertions.assertTrue(
plan.toString().matches("LogicalOlapScan \\( qualifier=db\\.table, output=\\[id#\\d+, name#\\d+] \\)"));
plan.toString().matches("LogicalOlapScan \\( qualified=db\\.table, output=\\[id#\\d+, name#\\d+] \\)"));
}
@Test

View File

@ -22,6 +22,7 @@ import org.apache.doris.catalog.Column;
import org.apache.doris.catalog.HashDistributionInfo;
import org.apache.doris.catalog.KeysType;
import org.apache.doris.catalog.OlapTable;
import org.apache.doris.catalog.PartitionInfo;
import org.apache.doris.catalog.Type;
import org.apache.doris.nereids.trees.plans.logical.LogicalOlapScan;
import org.apache.doris.thrift.TStorageType;
@ -41,31 +42,31 @@ public class PlanConstructor {
new Column("gender", Type.INT, false, AggregateType.NONE, "0", ""),
new Column("name", Type.STRING, true, AggregateType.NONE, "", ""),
new Column("age", Type.INT, true, AggregateType.NONE, "", "")),
KeysType.PRIMARY_KEYS, null, null);
score = new OlapTable(1L, "course",
KeysType.PRIMARY_KEYS, new PartitionInfo(), null);
score = new OlapTable(1L, "score",
ImmutableList.<Column>of(new Column("sid", Type.INT, true, AggregateType.NONE, "0", ""),
new Column("cid", Type.INT, true, AggregateType.NONE, "", ""),
new Column("grade", Type.DOUBLE, true, AggregateType.NONE, "", "")),
KeysType.PRIMARY_KEYS, null, null);
KeysType.PRIMARY_KEYS, new PartitionInfo(), null);
course = new OlapTable(2L, "course",
ImmutableList.<Column>of(new Column("cid", Type.INT, true, AggregateType.NONE, "0", ""),
new Column("name", Type.STRING, true, AggregateType.NONE, "", ""),
new Column("teacher", Type.STRING, true, AggregateType.NONE, "", "")),
KeysType.PRIMARY_KEYS, null, null);
KeysType.PRIMARY_KEYS, new PartitionInfo(), null);
student.setIndexMeta(-1,
"base",
"student",
student.getFullSchema(),
0, 0, (short) 0,
TStorageType.COLUMN,
KeysType.PRIMARY_KEYS);
score.setIndexMeta(-1,
"base",
"score",
score.getFullSchema(),
0, 0, (short) 0,
TStorageType.COLUMN,
KeysType.PRIMARY_KEYS);
course.setIndexMeta(-1,
"base",
"course",
course.getFullSchema(),
0, 0, (short) 0,
TStorageType.COLUMN,
@ -81,9 +82,9 @@ public class PlanConstructor {
ImmutableList.of(columns.get(hashColumn)));
OlapTable table = new OlapTable(tableId, tableName, columns,
KeysType.PRIMARY_KEYS, null, hashDistributionInfo);
KeysType.PRIMARY_KEYS, new PartitionInfo(), hashDistributionInfo);
table.setIndexMeta(-1,
"base",
tableName,
table.getFullSchema(),
0, 0, (short) 0,
TStorageType.COLUMN,