[SQL][Bug]fix semi/anti join error when table has delete sign column (#4498)
It is possible to report "Illegal column/field reference'table2.DORIS_DELETE_SIGN' of semi-/anti-join" when executing a semi/anti join statement on a table with hidden columns. This is because the filter conditions of semi/anti join cannot added in the where statement. Now we add delete flag related where predicate in OlapScanNode level.
This commit is contained in:
@ -655,7 +655,7 @@ public class Analyzer {
|
||||
// find table all name
|
||||
for (TupleDescriptor desc : tupleByAlias.get(tblName.toString())) {
|
||||
//result = desc;
|
||||
if (!isVisible(desc.getId())) {
|
||||
if (!colName.equalsIgnoreCase(Column.DELETE_SIGN) && !isVisible(desc.getId())) {
|
||||
ErrorReport.reportAnalysisException(ErrorCode.ERR_ILLEGAL_COLUMN_REFERENCE_ERROR,
|
||||
Joiner.on(".").join(tblName.getTbl(),colName));
|
||||
}
|
||||
|
||||
@ -22,7 +22,6 @@ import org.apache.doris.catalog.Catalog;
|
||||
import org.apache.doris.catalog.Column;
|
||||
import org.apache.doris.catalog.Database;
|
||||
import org.apache.doris.catalog.FunctionSet;
|
||||
import org.apache.doris.catalog.KeysType;
|
||||
import org.apache.doris.catalog.OlapTable;
|
||||
import org.apache.doris.catalog.Table.TableType;
|
||||
import org.apache.doris.catalog.Type;
|
||||
@ -340,7 +339,6 @@ public class SelectStmt extends QueryStmt {
|
||||
return;
|
||||
}
|
||||
super.analyze(analyzer);
|
||||
|
||||
fromClause_.setNeedToSql(needToSql);
|
||||
fromClause_.analyze(analyzer);
|
||||
|
||||
@ -533,21 +531,6 @@ public class SelectStmt extends QueryStmt {
|
||||
whereClause = new BoolLiteral(true);
|
||||
}
|
||||
}
|
||||
// filter deleted data by and DELETE_SIGN column = 0, DELETE_SIGN is a hidden column
|
||||
// that indicates whether the row is delete
|
||||
for (TableRef tableRef : fromClause_.getTableRefs()) {
|
||||
if (!isForbiddenMVRewrite() && tableRef instanceof BaseTableRef && tableRef.getTable() instanceof OlapTable
|
||||
&& ((OlapTable) tableRef.getTable()).getKeysType() == KeysType.UNIQUE_KEYS
|
||||
&& ((OlapTable) tableRef.getTable()).hasDeleteSign()) {
|
||||
BinaryPredicate filterDeleteExpr = new BinaryPredicate(BinaryPredicate.Operator.EQ,
|
||||
new SlotRef(tableRef.getName(), Column.DELETE_SIGN), new IntLiteral(0));
|
||||
if (whereClause == null) {
|
||||
whereClause = filterDeleteExpr;
|
||||
} else {
|
||||
whereClause = new CompoundPredicate(CompoundPredicate.Operator.AND, filterDeleteExpr, whereClause);
|
||||
}
|
||||
}
|
||||
}
|
||||
Expr deDuplicatedWhere = deduplicateOrs(whereClause);
|
||||
if (deDuplicatedWhere != null) {
|
||||
whereClause = deDuplicatedWhere;
|
||||
|
||||
@ -33,6 +33,7 @@ import org.apache.doris.analysis.GroupByClause;
|
||||
import org.apache.doris.analysis.GroupingInfo;
|
||||
import org.apache.doris.analysis.InPredicate;
|
||||
import org.apache.doris.analysis.InlineViewRef;
|
||||
import org.apache.doris.analysis.IntLiteral;
|
||||
import org.apache.doris.analysis.IsNullPredicate;
|
||||
import org.apache.doris.analysis.JoinOperator;
|
||||
import org.apache.doris.analysis.LiteralExpr;
|
||||
@ -52,6 +53,7 @@ import org.apache.doris.catalog.AggregateType;
|
||||
import org.apache.doris.catalog.Column;
|
||||
import org.apache.doris.catalog.FunctionSet;
|
||||
import org.apache.doris.catalog.MysqlTable;
|
||||
import org.apache.doris.catalog.OlapTable;
|
||||
import org.apache.doris.catalog.Table;
|
||||
import org.apache.doris.common.AnalysisException;
|
||||
import org.apache.doris.common.FeConstants;
|
||||
@ -1361,6 +1363,13 @@ public class SingleNodePlanner {
|
||||
switch (tblRef.getTable().getType()) {
|
||||
case OLAP:
|
||||
OlapScanNode olapNode = new OlapScanNode(ctx_.getNextNodeId(), tblRef.getDesc(), "OlapScanNode");
|
||||
if (((OlapTable) tblRef.getTable()).hasDeleteSign()) {
|
||||
Expr conjunct = new BinaryPredicate(BinaryPredicate.Operator.EQ,
|
||||
new SlotRef(tblRef.getAliasAsName(), Column.DELETE_SIGN), new IntLiteral(0));
|
||||
conjunct.analyze(analyzer);
|
||||
analyzer.registerConjunct(conjunct, tblRef.getDesc().getId());
|
||||
}
|
||||
|
||||
olapNode.setForceOpenPreAgg(tblRef.isForcePreAggOpened());
|
||||
scanNode = olapNode;
|
||||
break;
|
||||
|
||||
@ -64,11 +64,42 @@ public class SelectStmtTest {
|
||||
"\"storage_type\" = \"COLUMN\",\n" +
|
||||
"\"replication_num\" = \"1\"\n" +
|
||||
");";
|
||||
|
||||
String tbl1 = "CREATE TABLE db1.table1 (\n" +
|
||||
" `siteid` int(11) NULL DEFAULT \"10\" COMMENT \"\",\n" +
|
||||
" `citycode` smallint(6) NULL COMMENT \"\",\n" +
|
||||
" `username` varchar(32) NULL DEFAULT \"\" COMMENT \"\",\n" +
|
||||
" `pv` bigint(20) NULL DEFAULT \"0\" COMMENT \"\"\n" +
|
||||
") ENGINE=OLAP\n" +
|
||||
"UNIQUE KEY(`siteid`, `citycode`, `username`)\n" +
|
||||
"COMMENT \"OLAP\"\n" +
|
||||
"DISTRIBUTED BY HASH(`siteid`) BUCKETS 10\n" +
|
||||
"PROPERTIES (\n" +
|
||||
"\"replication_num\" = \"1\",\n" +
|
||||
"\"in_memory\" = \"false\",\n" +
|
||||
"\"storage_format\" = \"V2\"\n" +
|
||||
")";
|
||||
String tbl2 = "CREATE TABLE db1.table2 (\n" +
|
||||
" `siteid` int(11) NULL DEFAULT \"10\" COMMENT \"\",\n" +
|
||||
" `citycode` smallint(6) NULL COMMENT \"\",\n" +
|
||||
" `username` varchar(32) NULL DEFAULT \"\" COMMENT \"\",\n" +
|
||||
" `pv` bigint(20) NULL DEFAULT \"0\" COMMENT \"\"\n" +
|
||||
") ENGINE=OLAP\n" +
|
||||
"UNIQUE KEY(`siteid`, `citycode`, `username`)\n" +
|
||||
"COMMENT \"OLAP\"\n" +
|
||||
"DISTRIBUTED BY HASH(`siteid`) BUCKETS 10\n" +
|
||||
"PROPERTIES (\n" +
|
||||
"\"replication_num\" = \"1\",\n" +
|
||||
"\"in_memory\" = \"false\",\n" +
|
||||
"\"storage_format\" = \"V2\"\n" +
|
||||
")";
|
||||
dorisAssert = new DorisAssert();
|
||||
dorisAssert.withDatabase("db1").useDatabase("db1");
|
||||
dorisAssert.withTable(createTblStmtStr)
|
||||
.withTable(createBaseAllStmtStr)
|
||||
.withTable(createPratitionTableStr);
|
||||
.withTable(createPratitionTableStr)
|
||||
.withTable(tbl1)
|
||||
.withTable(tbl2);
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -411,4 +442,15 @@ public class SelectStmtTest {
|
||||
.explainQuery()
|
||||
.contains("`datekey` = 20200730"));
|
||||
}
|
||||
@Test
|
||||
public void testDeleteSign() throws Exception {
|
||||
String sql1 = "SELECT * FROM db1.table1 LEFT ANTI JOIN db1.table2 ON db1.table1.siteid = db1.table2.siteid;";
|
||||
Assert.assertTrue(dorisAssert.query(sql1).explainQuery().contains("`table1`.`__DORIS_DELETE_SIGN__` = 0"));
|
||||
String sql2 = "SELECT * FROM db1.table1 JOIN db1.table2 ON db1.table1.siteid = db1.table2.siteid;";
|
||||
Assert.assertTrue(dorisAssert.query(sql2).explainQuery().contains("`table1`.`__DORIS_DELETE_SIGN__` = 0"));
|
||||
String sql3 = "SELECT * FROM table1";
|
||||
Assert.assertTrue(dorisAssert.query(sql3).explainQuery().contains("`table1`.`__DORIS_DELETE_SIGN__` = 0"));
|
||||
String sql4 = " SELECT * FROM table1 table2";
|
||||
Assert.assertTrue(dorisAssert.query(sql4).explainQuery().contains("`table2`.`__DORIS_DELETE_SIGN__` = 0"));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user