[Fix](nereids) fix qualifier problem that affects delete stmt in another catalog (#33528)

* [Fix](nereids) fix qualifier problem that affects delete stmt in another catalog

* [Fix](nereids) fix qualifier problem that affects delete stmt in another catalog

* [Fix](nereids) fix qualifier problem that affects delete stmt in another catalog

* [Fix](nereids) fix qualifier problem that affects delete stmt in another catalog

---------

Co-authored-by: feiniaofeiafei <moailing@selectdb.com>
This commit is contained in:
feiniaofeiafei
2024-04-11 21:43:01 +08:00
committed by GitHub
parent 3d66723214
commit dc8da9ee89
5 changed files with 81 additions and 68 deletions

View File

@ -66,6 +66,7 @@ import org.apache.doris.qe.ConnectContext;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import org.apache.commons.collections.CollectionUtils;
@ -189,7 +190,7 @@ public class BindRelation extends OneAnalysisRuleFactory {
List<Long> tabletIds = unboundRelation.getTabletIds();
if (!CollectionUtils.isEmpty(partIds)) {
scan = new LogicalOlapScan(unboundRelation.getRelationId(),
(OlapTable) table, ImmutableList.of(tableQualifier.get(1)), partIds,
(OlapTable) table, tableQualifier, partIds,
tabletIds, unboundRelation.getHints(), unboundRelation.getTableSample());
} else {
Optional<String> indexName = unboundRelation.getIndexName();
@ -206,11 +207,11 @@ public class BindRelation extends OneAnalysisRuleFactory {
: PreAggStatus.off("For direct index scan.");
scan = new LogicalOlapScan(unboundRelation.getRelationId(),
(OlapTable) table, ImmutableList.of(tableQualifier.get(1)), tabletIds, indexId,
(OlapTable) table, tableQualifier, tabletIds, indexId,
preAggStatus, unboundRelation.getHints(), unboundRelation.getTableSample());
} else {
scan = new LogicalOlapScan(unboundRelation.getRelationId(),
(OlapTable) table, ImmutableList.of(tableQualifier.get(1)), tabletIds, unboundRelation.getHints(),
(OlapTable) table, tableQualifier, tabletIds, unboundRelation.getHints(),
unboundRelation.getTableSample());
}
}
@ -238,10 +239,12 @@ public class BindRelation extends OneAnalysisRuleFactory {
private LogicalPlan getLogicalPlan(TableIf table, UnboundRelation unboundRelation,
List<String> tableQualifier, CascadesContext cascadesContext) {
List<String> qualifierWithoutTableName = Lists.newArrayList();
qualifierWithoutTableName.addAll(tableQualifier.subList(0, tableQualifier.size() - 1));
switch (table.getType()) {
case OLAP:
case MATERIALIZED_VIEW:
return makeOlapScan(table, unboundRelation, tableQualifier);
return makeOlapScan(table, unboundRelation, qualifierWithoutTableName);
case VIEW:
View view = (View) table;
String inlineViewDef = view.getInlineViewDef();
@ -257,24 +260,25 @@ public class BindRelation extends OneAnalysisRuleFactory {
return new LogicalSubQueryAlias<>(tableQualifier, hiveViewPlan);
}
hmsTable.setScanParams(unboundRelation.getScanParams());
return new LogicalFileScan(unboundRelation.getRelationId(), (HMSExternalTable) table, tableQualifier,
unboundRelation.getTableSample());
return new LogicalFileScan(unboundRelation.getRelationId(), (HMSExternalTable) table,
qualifierWithoutTableName, unboundRelation.getTableSample());
case ICEBERG_EXTERNAL_TABLE:
case PAIMON_EXTERNAL_TABLE:
case MAX_COMPUTE_EXTERNAL_TABLE:
return new LogicalFileScan(unboundRelation.getRelationId(), (ExternalTable) table, tableQualifier,
unboundRelation.getTableSample());
return new LogicalFileScan(unboundRelation.getRelationId(), (ExternalTable) table,
qualifierWithoutTableName, unboundRelation.getTableSample());
case SCHEMA:
return new LogicalSchemaScan(unboundRelation.getRelationId(), table, tableQualifier);
return new LogicalSchemaScan(unboundRelation.getRelationId(), table, qualifierWithoutTableName);
case JDBC_EXTERNAL_TABLE:
case JDBC:
return new LogicalJdbcScan(unboundRelation.getRelationId(), table, tableQualifier);
return new LogicalJdbcScan(unboundRelation.getRelationId(), table, qualifierWithoutTableName);
case ODBC:
return new LogicalOdbcScan(unboundRelation.getRelationId(), table, tableQualifier);
return new LogicalOdbcScan(unboundRelation.getRelationId(), table, qualifierWithoutTableName);
case ES_EXTERNAL_TABLE:
return new LogicalEsScan(unboundRelation.getRelationId(), (EsExternalTable) table, tableQualifier);
return new LogicalEsScan(unboundRelation.getRelationId(), (EsExternalTable) table,
qualifierWithoutTableName);
case TEST_EXTERNAL_TABLE:
return new LogicalTestScan(unboundRelation.getRelationId(), table, tableQualifier);
return new LogicalTestScan(unboundRelation.getRelationId(), table, qualifierWithoutTableName);
default:
try {
// TODO: support other type table, such as ELASTICSEARCH

View File

@ -39,11 +39,11 @@ import org.apache.doris.nereids.trees.plans.PlanType;
import org.apache.doris.nereids.trees.plans.RelationId;
import org.apache.doris.nereids.trees.plans.algebra.CatalogRelation;
import org.apache.doris.nereids.util.Utils;
import org.apache.doris.qe.ConnectContext;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import org.apache.commons.lang3.StringUtils;
import java.util.List;
import java.util.Objects;
@ -57,7 +57,7 @@ import java.util.function.Supplier;
public abstract class LogicalCatalogRelation extends LogicalRelation implements CatalogRelation {
protected final TableIf table;
// [catalogName, databaseName, tableName]
// [catalogName, databaseName]
protected final ImmutableList<String> qualifier;
public LogicalCatalogRelation(RelationId relationId, PlanType type, TableIf table, List<String> qualifier) {
@ -82,13 +82,20 @@ public abstract class LogicalCatalogRelation extends LogicalRelation implements
public DatabaseIf getDatabase() throws AnalysisException {
Preconditions.checkArgument(!qualifier.isEmpty(), "qualifier can not be empty");
try {
CatalogIf catalog = qualifier.size() == 3
? Env.getCurrentEnv().getCatalogMgr().getCatalogOrException(qualifier.get(0),
s -> new Exception("Catalog [" + qualifier.get(0) + "] does not exist."))
: Env.getCurrentEnv().getCurrentCatalog();
return catalog.getDbOrException(qualifier.size() == 3 ? qualifier.get(1) : qualifier.get(0),
s -> new Exception("Database [" + qualifier.get(1) + "] does not exist in catalog ["
+ qualifier.get(0) + "]."));
int len = qualifier.size();
if (2 == len) {
CatalogIf<DatabaseIf> catalog = Env.getCurrentEnv().getCatalogMgr()
.getCatalogOrAnalysisException(qualifier.get(0));
return catalog.getDbOrAnalysisException(qualifier.get(1));
} else if (1 == len) {
CatalogIf<DatabaseIf> catalog = Env.getCurrentEnv().getCurrentCatalog();
return catalog.getDbOrAnalysisException(qualifier.get(0));
} else if (0 == len) {
CatalogIf<DatabaseIf> catalog = Env.getCurrentEnv().getCurrentCatalog();
ConnectContext ctx = ConnectContext.get();
return catalog.getDb(ctx.getDatabase()).get();
}
return null;
} catch (Exception e) {
throw new AnalysisException(e.getMessage(), e);
}
@ -110,9 +117,6 @@ public abstract class LogicalCatalogRelation extends LogicalRelation implements
* Full qualified name parts, i.e., concat qualifier and name into a list.
*/
public List<String> qualified() {
if (qualifier.size() == 3) {
return qualifier;
}
return Utils.qualifiedNameParts(qualifier, table.getName());
}
@ -120,9 +124,6 @@ public abstract class LogicalCatalogRelation extends LogicalRelation implements
* Full qualified table name, concat qualifier and name with `.` as separator.
*/
public String qualifiedName() {
if (qualifier.size() == 3) {
return StringUtils.join(qualifier, ".");
}
return Utils.qualifiedName(qualifier, table.getName());
}

View File

@ -31,6 +31,7 @@ import org.apache.doris.nereids.trees.plans.PlanType;
import org.apache.doris.nereids.trees.plans.RelationId;
import org.apache.doris.nereids.trees.plans.algebra.CatalogRelation;
import org.apache.doris.nereids.util.Utils;
import org.apache.doris.qe.ConnectContext;
import org.apache.doris.statistics.Statistics;
import com.google.common.base.Preconditions;
@ -85,13 +86,20 @@ public abstract class PhysicalCatalogRelation extends PhysicalRelation implement
public DatabaseIf getDatabase() throws AnalysisException {
Preconditions.checkArgument(!qualifier.isEmpty(), "qualifier can not be empty");
try {
CatalogIf catalog = qualifier.size() == 3
? Env.getCurrentEnv().getCatalogMgr().getCatalogOrException(qualifier.get(0),
s -> new Exception("Catalog [" + qualifier.get(0) + "] does not exist."))
: Env.getCurrentEnv().getCurrentCatalog();
return catalog.getDbOrException(qualifier.size() == 3 ? qualifier.get(1) : qualifier.get(0),
s -> new Exception("Database [" + qualifier.get(1) + "] does not exist in catalog ["
+ qualifier.get(0) + "]."));
int len = qualifier.size();
if (2 == len) {
CatalogIf<DatabaseIf> catalog = Env.getCurrentEnv().getCatalogMgr()
.getCatalogOrAnalysisException(qualifier.get(0));
return catalog.getDbOrAnalysisException(qualifier.get(1));
} else if (1 == len) {
CatalogIf<DatabaseIf> catalog = Env.getCurrentEnv().getCurrentCatalog();
return catalog.getDbOrAnalysisException(qualifier.get(0));
} else if (0 == len) {
CatalogIf<DatabaseIf> catalog = Env.getCurrentEnv().getCurrentCatalog();
ConnectContext ctx = ConnectContext.get();
return catalog.getDb(ctx.getDatabase()).get();
}
return null;
} catch (Exception e) {
throw new AnalysisException(e.getMessage(), e);
}

View File

@ -64,7 +64,7 @@ class BindRelationTest extends TestWithFeService implements GeneratedPlanPattern
Assertions.assertTrue(plan instanceof LogicalOlapScan);
Assertions.assertEquals(
ImmutableList.of(DEFAULT_CLUSTER_PREFIX + DB1, "t"),
ImmutableList.of("internal", DEFAULT_CLUSTER_PREFIX + DB1, "t"),
((LogicalOlapScan) plan).qualified());
}
@ -76,7 +76,7 @@ class BindRelationTest extends TestWithFeService implements GeneratedPlanPattern
Assertions.assertTrue(plan instanceof LogicalOlapScan);
Assertions.assertEquals(
ImmutableList.of(DEFAULT_CLUSTER_PREFIX + DB1, "t"),
ImmutableList.of("internal", DEFAULT_CLUSTER_PREFIX + DB1, "t"),
((LogicalOlapScan) plan).qualified());
}

View File

@ -70,18 +70,18 @@ public class ColumnPruningTest extends TestWithFeService implements MemoPatternM
logicalProject()
.when(p -> getOutputQualifiedNames(p).containsAll(
ImmutableList.of(
"test.student.id",
"test.student.name"))),
"internal.test.student.id",
"internal.test.student.name"))),
logicalProject().when(
p -> getOutputQualifiedNames(p).containsAll(
ImmutableList.of(
"test.score.sid",
"test.score.grade")))
"internal.test.score.sid",
"internal.test.score.grade")))
))
.when(p -> getOutputQualifiedNames(p)
.containsAll(
ImmutableList.of("test.student.name",
"test.student.id")))
ImmutableList.of("internal.test.student.name",
"internal.test.student.id")))
)
)
);
@ -102,18 +102,18 @@ public class ColumnPruningTest extends TestWithFeService implements MemoPatternM
logicalProject()
.when(p -> getOutputQualifiedNames(p).containsAll(
ImmutableList.of(
"test.student.id",
"test.student.name",
"test.student.sex"))),
"internal.test.student.id",
"internal.test.student.name",
"internal.test.student.sex"))),
logicalRelation()
))
.when(p -> getOutputQualifiedNames(p)
.containsAll(
ImmutableList.of("test.student.name",
"test.score.cid",
"test.score.grade",
"test.student.sex")))
ImmutableList.of("internal.test.student.name",
"internal.test.score.cid",
"internal.test.score.grade",
"internal.test.student.sex")))
)
)
);
@ -129,9 +129,9 @@ public class ColumnPruningTest extends TestWithFeService implements MemoPatternM
logicalFilter(
logicalProject().when(p -> getOutputQualifiedNames(p)
.containsAll(ImmutableList.of(
"test.student.name",
"test.student.id",
"test.student.age")))
"internal.test.student.name",
"internal.test.student.id",
"internal.test.student.age")))
)
)
);
@ -155,25 +155,25 @@ public class ColumnPruningTest extends TestWithFeService implements MemoPatternM
logicalProject(logicalRelation())
.when(p -> getOutputQualifiedNames(
p).containsAll(ImmutableList.of(
"test.student.id",
"test.student.name"))),
"internal.test.student.id",
"internal.test.student.name"))),
logicalRelation()
)).when(p -> getOutputQualifiedNames(p)
.containsAll(ImmutableList.of(
"test.student.name",
"test.score.cid",
"test.score.grade"))),
"internal.test.student.name",
"internal.test.score.cid",
"internal.test.score.grade"))),
logicalProject(logicalRelation())
.when(p -> getOutputQualifiedNames(p)
.containsAll(ImmutableList.of(
"test.course.cid",
"test.course.cname")))
"internal.test.course.cid",
"internal.test.course.cname")))
)
).when(p -> getOutputQualifiedNames(p).containsAll(ImmutableList.of(
"test.student.name",
"test.course.cname",
"test.score.grade")))
"internal.test.student.name",
"internal.test.course.cname",
"internal.test.score.grade")))
)
)
);
@ -280,12 +280,12 @@ public class ColumnPruningTest extends TestWithFeService implements MemoPatternM
logicalProject(logicalRelation())
.when(p -> getOutputQualifiedNames(p)
.containsAll(ImmutableList.of(
"test.student.id",
"test.student.name"))),
"internal.test.student.id",
"internal.test.student.name"))),
logicalProject(logicalRelation())
.when(p -> getOutputQualifiedNames(p)
.containsAll(ImmutableList.of(
"test.score.sid")))
"internal.test.score.sid")))
)
)
);
@ -304,10 +304,10 @@ public class ColumnPruningTest extends TestWithFeService implements MemoPatternM
logicalProject(
logicalOlapScan()
).when(p -> getOutputQualifiedNames(p).equals(
ImmutableList.of("test.student.id")
ImmutableList.of("internal.test.student.id")
))
).when(agg -> getOutputQualifiedNames(agg.getOutputs()).equals(
ImmutableList.of("test.student.id")
ImmutableList.of("internal.test.student.id")
)))
)
)